When an MCP client calls a tool through a Celigo MCP server, Celigo automatically provides a context object with information about the caller, the credential used, the MCP server that received the call, and information reported by the MCP client.
You can use this information to return caller-specific data through a shared connection. For example, configure a tool to retrieve only the records belonging to the end user who called it.
No additional configuration is required. Tools that don't reference context continue to work as before.
Understand caller context
The context object contains the following information:
| Object | Description |
|---|---|
context.byUser |
The authenticated caller's _id, name, email, accessLevel, and _aShareId, when available. For end users on MCP servers using Celigo Identity, it also includes groups and roles. |
context.token |
Information about the credential used. type is oauth for a signed-in user, personal for a personal access token, or service for an API token. OAuth includes only type. Personal access tokens and API tokens also include _id, name, and autoPurgeAt when an expiration is configured. API tokens can include fullAccess and scoped resource IDs. |
context.source |
Information about what invoked the tool: type, _id, and name. The type is mcpServer, and the ID and name identify the MCP server that received the call. |
context.client |
Information reported by the MCP client, including name, version, title, and trace information (traceparent, tracestate, and baggage). Fields may be absent when the client doesn't provide them. |
Celigo provides byUser, token, and source from the authenticated request. [CTX-1: insert Tyler's approved second sentence here before publishing.]
context.byUser and context.token use the same fields as the GET /v1/tokenInfo response, with two differences: context.byUser is absent for API tokens, and groups and roles appear only in caller context for end users using Celigo Identity.
Important: context.client contains information reported by the MCP client and isn't verified by Celigo. Don't use it for access control or routing.
Who appears in context.byUser
The available caller information depends on how the MCP server authenticates the request.
| How the caller connects | context.byUser |
context.token.type |
|---|---|---|
| End user signs in through Celigo Identity | The end user, with accessLevel set to null, _aShareId, groups, and roles
|
oauth |
| Account owner signs in through Celigo Identity | The account owner, with accessLevel set to owner, and no _aShareId, groups, or roles
|
oauth |
| Personal access token | The workspace user who owns the token, with their access level and _aShareId, and no groups or roles
|
personal |
| API token | Absent | service |
If Celigo can't identify the caller, context.byUser is absent and the tool still runs. Use context.token.type and the presence of context.byUser to distinguish callers.
Values that need care
-
Access level:
accessLevelcan beowner,administrator,manage,monitor, ornull. It'snullfor end users and integration-only workspace users, and might be absent when Celigo can't determine the caller's share. Anullvalue renders as the textnullin handlebars expressions. Use{{#if context.byUser.accessLevel}}to check whether a value exists, and treat missing ornullvalues as no account-level access. -
Groups and roles: These fields appear for end users authenticated through Celigo Identity. Each contains a list of objects with
_idandname. Roles include direct assignments and roles inherited through groups. An empty array ([]) means there are no assignments; a missing field means the information doesn't apply or couldn't be retrieved. When using memberships to grant access, treat missing fields as no access. -
Caller name: If the identity provider doesn't supply a name,
context.byUser.namemight contain the caller's email address. Usecontext.byUser.emailto identify the caller.
Reference caller context in a tool
You can reference caller context in supported handlebars expressions, including database queries, HTTP request URLs, headers, bodies, Mapper 2.0 mappings, transformations, and filters.
For example, to reference the caller's email address:
{{context.byUser.email}}In JavaScript hooks and scripts, including branching scripts, use:
options.context.byUser.email
In a filter rule, select a field from the context section, such as byUser.email.
Note: Caller context isn't available in Mapper 1.0 field mappings, Salesforce or NetSuite dynamic lookups, SuiteScript hooks, or HTTP connection-level transforms. In Mapper 2.0, use a handlebars expression such as {{context.byUser.email}}. A JSON path such as $.context.byUser.email refers to caller context only when the mapping's input context is set to Envelope. When it's set to Record, the same path refers to the tool's input record.
Example: Return records for the authenticated caller
Suppose multiple end users call a tool that retrieves orders from a database using a shared connection.
To return only the caller's orders, filter the query using their email address:
SELECT id, amount, owner_email
FROM orders
WHERE owner_email = {{context.byUser.email}}In a database query, Celigo inserts the value as a quoted, escaped SQL string. Don't add quotation marks around the expression or use triple braces ({{{ }}}), which insert values without escaping them.
For example, when user@example.com calls the tool, the query runs with:
WHERE owner_email = 'user@example.com'
If caller information is unavailable, such as for an API-token request, the query fails and returns no records.
Avoid returning every record
When you use caller context to restrict data access, make sure missing caller information doesn't cause the tool to return unrestricted results.
Don't make the filter conditional
A conditional filter can return every record when caller information is missing.
Avoid:
SELECT id, amount, owner_email FROM orders
{{#if context.byUser}}WHERE owner_email = {{context.byUser.email}}{{/if}}Use:
SELECT id, amount, owner_email FROM orders
WHERE owner_email = {{context.byUser.email}}Always include the filtering condition.
When a required caller value is missing, database queries, HTTP request URLs, and headers that reference it fail. However, HTTP request bodies and mappings can render missing values as empty text. Make sure an empty value can't match unintended records.
The same applies to scripts. If options.context or options.context.byUser is missing, return no records or throw an error instead of skipping the filter.
Don't call a caller-filtered tool from flows, APIs, or AI agents
Celigo provides caller context when an MCP server runs a tool, including any tool that the tool calls as a step. When a flow, API, or AI agent runs the same tool, caller context isn't available.
Avoid: Using a caller-filtered tool through both an MCP server and other execution paths without handling missing context.
Use: Make caller-filtered tools available only through MCP servers. If the tool must also run elsewhere, stop execution when caller information is missing. For example, use a JavaScript filter on the step that retrieves the data:
function filter(options) {
return Boolean(
options.context &&
options.context.byUser &&
options.context.byUser.email
);
}Scripts read caller context from options.context, not from the input record.
Important: If you use caller context to restrict data access, ensure that requests without caller information fail or return no records. Never skip the filtering condition when context.byUser is unavailable.
Test caller context
When you preview or test a tool, Celigo provides sample caller context, including sample.user@example.com, sample credential details, and MCP server information.
To test an expression with different caller values:
- Open the handlebars editor for the field.
- Under resources available for your handlebars template in handlebar editor, change a value in
context, such ascontext.byUser.email. - Select Preview to see the result.
To test a missing value, remove the corresponding key from the sample context. These changes apply only to the current preview and aren't saved.
Note: Tool test runs always use the original sample caller information. In a test run, an import step writes these sample values to its destination, the same way it writes mock input. To test actual callers or API-token requests, call the tool through its MCP server.
View caller context in execution logs
Celigo adds caller context during execution, so it doesn't appear in the original MCP Request.
When the MCP server uses Detailed log or Debug, you can review resolved caller context values in the tool's execution steps wherever those values were used, such as HTTP request URLs, headers, or bodies. Trace view doesn't display caller context as a separate entry or show the rendered query of a database step.
For more information, see View MCP server request history and execution logs.
Note: When a tool call fails, Celigo replaces caller details, such as names, email addresses, group and role information, and token names, with [redacted] in the error returned to the MCP client. Successful results aren't changed.
Considerations
- Caller context is available when an MCP server runs a tool built in Celigo, including any tool that the tool calls as a step. Tools executed through flows, APIs, or AI agents don't receive caller context.
- APIs exposed through MCP servers and capabilities added through MCP proxies don't receive caller context.
-
context.byUseris absent for API-token calls, OAuth sign-ins through Token validation, and requests where Celigo can't identify the caller. - If a tool uses an on-premise agent, the agent must meet the minimum supported version to access caller context.