Skip to main content

MCP Integration

Anyy connects local stdio commands and remote HTTP MCP servers using a Profile and its project configuration. Each server has its own enabled setting, connection configuration, and tool exposure. Adding a server saves an enabled lazy configuration by default; it does not probe or ask you to select a tool list. Use --disable to save it disabled.

Connection prerequisites​

Supported client transports are stdio and Streamable HTTP (http). A separate sse transport is rejected; HTTP can still carry event streams as part of Streamable HTTP. Remote endpoints must use HTTPS, except loopback HTTP URLs.

For stdio, install the server executable and its dependencies on the machine running Anyy. An npx command requires Node.js/npm there; Anyy does not bundle those runtimes or install that server for you. Only a limited process environment (including PATH and HOME) is inherited; set other required values explicitly with server env. HTTP servers do not require a local Node.js runtime.

Profile and project configuration​

Global server definitions live in the Profile's config.yaml, under mcp.client.servers. The project file is .anyy/mcp.json in that Profile's canonical Workspace (currently <ProfileHome>/workspace/.anyy/mcp.json). Switching conversations or changing a Session's working directory does not choose another project file.

The project file uses a mcpServers object:

{
"mcpServers": {
"context": {"enabled": false, "exposure": "deferred"},
"project-docs": {"url": "https://mcp.example.com", "exposure": "codemode"}
}
}

A full project definition replaces the same-name Profile definition. An entry without command, url or type is a partial override: it requires a same-name Profile server and may contain only enabled, exposure and toolExposure. Each supplied value replaces its inherited value; toolExposure replaces the complete ordered rule object. Other fields, including authentication, continue to come from the Profile definition. A full project definition cannot set a provider auth reference.

Use anyy mcp show SERVER_ID to inspect the selected configuration source and any project override. Malformed project configuration appears in configuration diagnostics rather than silently becoming a different server definition.

Add or remove a project definition​

anyy mcp add project-docs --local --url https://mcp.example.com
anyy mcp remove project-docs --local

--local (or -l) writes only this Profile's project file. Add replaces the same-name project entry without --force; remove deletes only that entry, preserves Profile definitions and saved grants, and reports an error if that project entry is absent. These file edits do not reconnect a running server. Startup or an idle session.reload loads the new definition; removing a same-name override then reveals the Profile definition. Without --local, add/remove keeps the ordinary Profile behavior.

Values and paths​

Ordinary add/configure/set and Dashboard saves keep the value string you enter, even for a sensitive-looking environment or header name or an OAuth client secret. They do not automatically turn it into a Secret reference. Use an explicit secret: reference when you want an existing Anyy-managed secret; ordinary strings keep the expression behavior below.

Only stdio environment values, HTTP header values and OAuth clientSecret use value expressions. $VAR and ${VAR} read the Anyy process environment; $$ produces a literal $, and $! produces a literal !. A value beginning with ! runs a local shell command and uses its trimmed output. This evaluation happens once: an expanded value is not evaluated again. Commands run in Anyy's process working directory, with a 10-second limit and a 1 MiB output limit.

In Profile definitions, values beginning with the exact prefixes env:, secret: or file: use Anyy's existing credential resolver first, and its result is final. In a full project definition those prefixes are literal text. A partial override inherits the Profile definition's value interpretation. URLs and other OAuth fields, such as clientId, scope and callbackUrl, do not use these expressions.

Command and argument paths expand a leading ~; cwd also supports a home-relative or Workspace-relative path. They do not run $ or ! expressions. The stdio working directory is separate from both the advertised Workspace root and the process directory used by !command.

Add a Local Server​

anyy mcp add context \
--transport stdio \
--command npx \
--exposure codemode \
--args -y @upstash/context7-mcp

Place Anyy options before --args or --; remaining arguments are passed to the server. Optional --cwd DIR is for stdio servers and accepts the same absolute, Workspace-relative or leading-home paths as the saved cwd; the entered path is not trimmed. Repeat --env KEY=VALUE as needed, using secret references for sensitive values. A local server runs with the operating-system access of Anyy.

Add a Remote Server​

anyy mcp add remote-docs --url https://mcp.example.com
anyy mcp add provider-docs --url https://mcp.example.com --auth '{"provider":"provider-id"}'
anyy mcp add header-docs --url https://mcp.example.com --header Authorization=secret:mcp/header-docs/token

HTTP supports automatic OAuth when no provider reference or Authorization header is configured. An anonymous server can connect without signing in; no initial token does not by itself mean reauthentication is required. auth is a provider JSON object; oauth is a separate typed options object. For example, pass --oauth '{"clientId":"registered-client"}' for an existing registration. The old oauth, header, and none string selectors are rejected.

Save the server before starting a login:

anyy mcp login remote-docs

When the server rejects saved OAuth client credentials, Anyy can clear the rejected local authorization state and recover once; it may ask you to sign in again. This does not replay a tool call. A missing code-exchange verifier ends that login attempt.

Browser callback and manual redirect​

Run anyy mcp login remote-docs --timeout 300, or select Sign in on the saved server in Dashboard or Tools & MCP in TUI setup. Complete authorization in your browser. If the browser cannot reach the machine running Anyy, paste the full redirect URL from its address bar into that login's input. Keep this URL private.

The CLI's timeout defaults to 300 seconds and covers authorization only, not connection checks or the reconnect after login. It first checks the connection: if already ready, it reports Already signed in; an ordinary connection error does not start a login. Explicit CLI login can authenticate a saved disabled server without enabling its tools. In a non-interactive terminal, the CLI waits only for the browser callback and does not read a pasted URL.

TUI uses Ctrl+Y to copy the complete authorization link and Esc to cancel. Closing the Dashboard login or leaving the page cancels its pending login. Completion clears the temporary link and input.

If a tool call needs an interactive OAuth grant or additional scopes, the connection reports that sign-in is required. Start sign-in explicitly from CLI, Dashboard or TUI. The failed call is not automatically refreshed or replayed. Cancelling sign-in ends that login attempt with the dedicated sign-in cancellation result; it does not continue authorization in the background.

Login from another process​

When another login process saves credentials for the same Profile/server, a connection waiting for authentication checks them when a model turn starts. A request already prepared for that turn keeps its original tool declarations; newly discovered tools appear when a later request is prepared. Anyy does not poll credentials in the background. Hand-edited configuration still needs a startup or idle Session resource reload; changing credentials does not restart an ordinary failed or closed connection through this detection path.

Sign out​

anyy mcp logout remote-docs

Use the exact configured Server ID. This removes the current local credential entry and closes the connection; it keeps server configuration and cached tools/resources/instructions. No saved entry is a successful no-op. It does not revoke remote tokens, and a recognized older fallback may require another logout. The command uses the resident Profile when available; it does not treat a timeout or failed resident reply as permission to alter files offline.

MCP does not periodically poll the tool catalog. Tools are discovered or refreshed on connection, explicit operations and real tool-list change notifications; the notification connection and supported session recovery remain.

The per-server connect_timeout_ms setting is retired; remove it from older configuration. call_timeout_ms applies separately to initialization, discovery and tool requests; opening has no additional total deadline. Eligible initial HTTP failures may be retried twice before a final connection error.

HTTP streams and token refresh​

After initialization, the default HTTP transport opens a separate GET stream for server requests and notifications. Provider-backed authentication obtains the current token at each actual HTTP dispatch, including that GET; it does not save an extra MCP copy of the Provider token. This transport behavior does not add a Dashboard or Profile switch.

The HTTP client preserves configured headers without adding a localhost Origin for loopback servers. An explicitly configured Origin is not overwritten. Servers still apply their own Origin validation.

Anyy can resume an interrupted event stream when the server supplied a cursor. It continues that stream with a GET request and its last event ID; it does not send the tool call again. Without a cursor, a response stream that ends before answering fails that request. Closing the connection stops recovery.

Processes using the same Profile/server credentials also coordinate token refresh and reread the saved token before requesting another refresh. This coordination does not promise recovery from every crash or lost-lease outcome.

Initialization and workspace roots​

A server's initialization result must provide a string protocolVersion, an object capabilities, and serverInfo with string name and version. Optional instructions must be a string. An invalid result closes the connection rather than marking the server connected. Missing, empty and untrimmed instructions remain distinct; the prompt-summary consumer trims them for display.

Servers requesting roots/list receive the resident Workspace's canonical directory as one file root. That root is fixed when the MCP manager is created; switching conversations or a logical Workspace does not redirect the shared connection.

A local stdio process defaults to that directory. Its configured cwd may be absolute, relative to it, or use leading home syntax; command and argument paths also support leading home syntax. Whitespace in cwd is preserved. Changing process cwd does not change the advertised Workspace root. The root supplies context, not a filesystem permission boundary.

Tool Exposure and Discovery​

ExposureUse
codemodeDefault; discovered and invoked through Codemode
deferredDiscovered through tool search
directDeclared directly to the model
hiddenUnavailable to model and Codemode discovery

The ordered toolExposure object overrides the server default. Exact names take precedence; otherwise the first matching wildcard wins. Configure it without a discovery prompt:

anyy mcp configure context --exposure deferred
anyy mcp set context description 'Documentation tools'
anyy mcp set context toolExposure '{"get-*":"deferred","*":"hidden"}'

Enabled and exposure settings save to the selected defining file or its existing project override. Changing exposure updates the available tool declarations without reconnecting the server; enable/disable affects only that server. If the connection fails after the setting was saved, inspect its connection status; the saved setting remains.

For a Profile server with no project override yet, use anyy mcp disable SERVER_ID --project or enable SERVER_ID --project to save only its enabled state in the project file. This option does not apply to full project definitions or already-overridden servers; ordinary enable/disable uses their selected source.

configure --description and --tool-exposure, and generic set/unset, edit the raw Profile definition. Do not combine these with configure --exposure or --enable; run separate commands. To change a project toolExposure override, edit that project entry rather than a hidden Profile definition.

These fields follow fixed Pi v1.2 MCP configuration and registration. Anyy's RPC tool_exposure is a JSON string that preserves rule order across the RPC map boundary; the saved configuration contains one ordered toolExposure value.

MCP tools do not generate or activate mcp-* personal toolsets. Ordinary personal toolsets, Roles, and parent tool-name restrictions remain separate. The global mcp.client.enabled, tools.include, tools.exclude, tools.trusted, --include, --exclude, --activate-toolset, and the old selection prompt are retired. Remove these fields from older configuration; they are rejected instead of ignored.

Server summaries in the prompt​

Anyy adds an mcp_servers section when a run starts. It lists enabled servers configured for Codemode or deferred discovery, including servers still connecting. Direct-only, hidden-only and disabled servers are omitted; a mixed server uses the Codemode label when both discovery routes are configured. A listing is a discovery hint, not a connection-success receipt.

Your configured description takes priority. Otherwise, the summary uses the first line of the server's available instructions. Names are sorted, summaries are shortened, and a bounded list counts any omitted servers. Keep descriptions concise; they are not a place for credentials.

This section stays fixed through the run's subsequent tool turns. A changed description, configuration or newly available instructions appears at the next prompt. If no server qualifies, the section is removed.

Inspect and Call Tools​

anyy mcp show context
anyy mcp probe context
anyy mcp test context
anyy mcp list
anyy mcp status --json
anyy mcp logs context
anyy mcp reload context
# If the inspected server advertises a search tool with a query field:
anyy mcp call docs.search --args '{"query":"Anyy"}'

The call above is illustrative: use the original server tool name and exact arguments shown by show/probe. Anyy's model-visible MCP names are namespaced and may be sanitized or collision-suffixed; Codemode discovery returns their JavaScript identifiers. Use the live declaration instead of constructing a name. See Codemode discovery and Tool Search.

anyy mcp reload reconnects using the configuration already loaded; it does not reread edited files. Startup and an idle Session's session.reload RPC load the Profile and project files again. There is no separate MCP file watcher. See applying changes.

Probe is optional and does not gate saving or enabling. Its single tools inventory contains name, visible_name, description, exposure, and offered facts. An offered tool is currently advertised by the server; it is not an approval result. A prepared call resolves the current server and offering when it executes.

New direct calls validate against the tool's current JSON Schema. A call already prepared before configuration replacement retains its declared schema and validated arguments, then resolves the current server when it executes. Replacement closes old in-flight connections without replaying their calls on the new server. Selected model tools and anyy mcp call execute directly, including writes. Profile ownership, server authentication, credential protection, and normal tool-name restrictions still apply. The old approval/execution-policy keys remain rejected.

Resources and templates​

Anyy provides three shared resource tools:

ToolInputProgrammatic result
list_mcp_resourcesOptional server, cursorresources, optional server, nextCursor, errors
list_mcp_resource_templatesOptional server, cursorresourceTemplates, optional server, nextCursor, errors
read_mcp_resourceRequired server, uri{server, uri, contents}

Specify a server to list one page, then pass its nextCursor for the next page. Omit the server to collect all pages from eligible servers; a cursor requires a server. Combined listings preserve successful results and identify failed servers in errors. A selected-server failure rejects the call.

Availability follows enabled servers with a reported resource capability and a non-hidden server exposure. The shared tools use the widest eligible exposure: direct, then codemode, then deferred. They appear after resource capability is known; withdrawal hides previously registered definitions. Resource inventories are fetched when called, not at startup.

Read results preserve complete programmatic JSON. Model output uses text, images or saved file references; long text follows the shared 20 KiB output limit. MCP App UI resources are omitted from these lists. A delivery failure does not repeat a successful resource read.

The old per-server resource/prompt tool names and tools.resources/tools.prompts switches are retired. Remove these switches from server configuration; their presence is rejected, including false or null. Status retains resources_advertised, prompts_advertised and server_capabilities, and removes the old enabled/posture/count fields for resources and prompts. Raw SDK prompt methods remain protocol APIs rather than generated Agent tools.

Connect another MCP client to Anyy​

anyy mcp serve exposes the resident assistant's conversation, message and event interfaces over stdio. Its default tools are conversations_list, conversation_get, messages_read, events_poll, events_wait, and messages_send.

mcp.server.scopes supports only conversations and messaging. Omitting it includes both; [] exposes no tools. Approval listing/response tools have been removed. Configuration rejects the old approvals scope, unimplemented scope placeholders, and the retired expose_approvals/expose_tools keys. Operations still go through the existing Gateway RPCs.

Conversation result API​

messages_send accepts only session_id and text:

{"session_id":"ses_example","text":"Summarize my tasks"}

It admits the input through session.submit, then calls execution.await with the original submission_id. The result's JSON text content contains:

FieldMeaning
submissionOriginal admission receipt, including its submission_id
executionObserved state and outcome for that input's actual invocation
messagesOrdered result messages loaded from that invocation's recorded references
timed_outWhether observation expired before a result became available

A later prompt in the same Session cannot replace these messages. messages_read is a history query and is not a fallback answer source. Normal protection and attachment handling still apply.

The MCP result has isError=false for a successful completion or an actual clarification suspension. A suspended state preserves its clarification handles and means the assistant needs input; it is not a final answer. Failure, interruption, cleared input, timeout or a nonfinal state has isError=true. An idle lane is successful only with outcome=succeeded.

For clients using Gateway RPC directly, preserve both IDs from admission:

{"execution_id":"exec_example","submission_id":"sub_example","timeout_ms":30000}

execution.await returns {execution, submission_id, timed_out, messages}. Waiting follows the original reserved or selected run and its recovery lineage, including a preparation failure before input selection. Cleared unselected input resolves with outcome=interrupted, stop_reason=input_cleared, and no result messages. Waiting never activates queued input.

A timeout returns timed_out=true with an empty messages array. Timeout or caller cancellation ends observation only; accepted work continues. An execution_id alone observes the reusable lane and does not identify the result of one submitted prompt. Inspect the session before submitting a timed-out request again.

Disable or Remove​

anyy mcp disable context
anyy mcp remove context

Disabling preserves configuration. Removing an MCP server definition from the Profile configuration deletes that definition and clears its Anyy-managed credentials; remove --local only removes the project entry and preserves grants. Ordinary personal toolsets are preserved. For operations on MCP server definitions in the Profile, --force confirms replacement or removal in scripts; it does not bypass Profile ownership or credential handling.

Troubleshooting​

ProblemCheck
Local server does not startCommand, arguments, executable, and environment
Remote server is unauthorizedProvider reference, OAuth state, or protected header
Tool is unavailableServer enabled state, exposure, and current offering
Tool schema changedInspect the current tool definition and retry with valid arguments
Runtime still shows old file contentsReread configuration through an idle Session reload or restart, then inspect the selected source

See Dashboard MCP for forms and inspection.

Results and Attachments​

Programmatic results preserve accepted MCP protocol values, including null, false, numbers, strings, and arrays in structuredContent. When the result has content blocks, Anyy converts those blocks to model content without appending structuredContent separately. If the content array is empty and structuredContent is present, Anyy formats that JSON as a model text block. This fallback text passes through the same credential protection and 20 KiB output handling as other MCP text. Output schemas affect the declared programmatic return; they do not turn remote structured results into a local validation gate. Model content preserves ordered text and images. Audio and unknown blocks use Pi's textual placeholders; embedded resources become text/images or saved binary files. Text over 20 KiB uses the saved full output and head/tail projection.

A resolved remote isError remains an error result. A transport or JSON-RPC exception rejects the call. Image and saved-file delivery uses the existing Session-owned Artifact path, preserves order, and does not repeat a remote call when delivery fails. Text is protected before saving. Saves start for all blocks before conversion awaits their completion, so an invalid block can reject conversion while started saves finish.

Ordinary network failures do not automatically replay tool calls; expired-session recovery is a separate case. OAuth registration, token refresh and transport requirements depend on the external service. Inspect its actual connection and tool result before relying on it.