Connect through MCP
Connect an MCP client to CODEXIS AI Agent, send attachments and follow responses.
MCP connects CODEXIS AI Agent to the application you work in. The connected client can manage projects, agents and chats, send messages with attachments and follow their progress. A hosted server connection requires its URL and an API key for an account with an active licence. Local stdio also requires an available codexis-agent-cli executable.
For application-specific setup, see MCP in Claude and Codex. The sections below cover server options and tool behavior. Operations use Codexis AI agent API v2 under the key owner’s account and consume its credits.
Local connection over stdio
The MCP client starts the process and communicates over standard input and output. The default transport is stdio.
codexis-agent-cli mcp servePass credentials to the process through environment variables, or use a profile saved through the CLI. Set the address to an origin such as https://vm.codexis.ai; the CLI adds the API path.
CODEXIS_AGENT_ENDPOINTstring, the address of your CODEXIS AI Agent instance.CODEXIS_AGENT_API_KEYstring, your API key.
The JSON below illustrates a generic process launch configuration. Supply command, args and env in the format your client uses to configure MCP servers. Replace api-YOUR_KEY with your own key.
{
"command": "codexis-agent-cli",
"args": ["mcp", "serve"],
"env": {
"CODEXIS_AGENT_ENDPOINT": "https://vm.codexis.ai",
"CODEXIS_AGENT_API_KEY": "api-YOUR_KEY"
}
}For a connection intended for reading, add --read-only. The server then allows reading data and observing a running response; attempts to change data return READ_ONLY. You can also set CODEXIS_AGENT_READ_ONLY=true.
codexis-agent-cli mcp serve --read-onlyHTTP connection
The hosted MCP address is https://vm.codexis.ai/mcp. Enter this URL and an X-Api-Key header containing your API key in your client. See the Claude and Codex setup guide for client configuration.
Use this command to run your own local HTTP server at http://127.0.0.1:3000/mcp.
codexis-agent-cli mcp serve \
--transport http \
--endpoint https://vm.codexis.aiIn your MCP client, select an HTTP connection, enter this URL and add the X-Api-Key header containing your API key to every request. The server uses the key from the incoming request, so each client works under its own account. You can also pass the backend origin to the server through CODEXIS_AGENT_ENDPOINT.
--hoststring, optional, the IP address orlocalhoston which the server listens. Default:127.0.0.1.--portinteger, optional, the server port. Default:3000.--allowed-hoststring, optional, an allowed hostname in the incoming HTTPHostheader, without a port. Repeat for multiple names. Defaults:localhost,127.0.0.1and[::1].--read-onlyboolean, optional, enables read-only mode for all clients of this server.
When exposing the server through your own domain, set the matching --allowed-host and provide HTTPS through a reverse proxy in front of the server. Transmit the API key over an encrypted connection.
First call
After connecting, the client discovers tools through MCP tools/list. To check the account, call identity_get with empty arguments. Examples in this section are the parameters of an MCP tools/call request.
{
"name": "identity_get",
"arguments": {}
}Tools return their result in structuredContent and also as JSON in the text content. Operation errors have isError: true and a code in structuredContent.error.code. Invalid parameters may produce a text-only error in content; an unknown tool produces a protocol error.
Use project_list, agent_list and chat_list to browse saved data. Create records with project_create, agent_create and chat_create; each type also has tools to get details, update and delete. Paginated lists return nextCursor, which you pass as cursor in the next call with the same filters.
Create a chat with chat_create. You can provide an agentId from agent_list or choose a model from model_list. The response contains the chat's id, which you then pass to message_send as chatId. To apply a saved agent’s instructions to a message, also pass its ID in agentIds when calling message_send.
Send a message and follow its response
The main fields accepted by message_send are listed below.
chatIdstring, UUID, required, the ID of an existing chat.messagestring, the message text. Send text, an attachment or both.requestIdstring, UUID, optional, the identifier for this particular submission. To recover after a disconnection, create and store it before calling the tool.attachmentIdsstring[], optional, IDs of attachments uploaded beforehand.attachmentsobject[], optional, attachments to upload with the message.
An accepted message returns requestId, chatId, userMessageId and assistantMessageId. Use assistantMessageId as messageId when observing the response. If the connection drops during submission, check its state with message_request_get using the original chatId and requestId before trying again.
Attachments
Upload a file beforehand with attachment_upload. The response has an items array containing the attachment ID; pass it in message_send.attachmentIds. The attachment moves to the message when it is sent. Until then, read its metadata with attachment_get or remove it with attachment_delete.
You can send small attachments directly as base64 over either transport. The limit is 32 KiB of decoded content per file. An entire HTTP request is limited to 64 KiB, including JSON and base64, so upload larger sets of attachments in separate calls and pass their IDs with the message.
This example uploads note.txt containing Hello followed by a newline.
{
"name": "attachment_upload",
"arguments": {
"source": {
"name": "note.txt",
"base64": "SGVsbG8K"
}
}
}For local files on macOS and Linux, start the stdio server with an allowed directory. Repeat --allow-path to allow multiple directories.
mkdir -p documents
codexis-agent-cli mcp serve --allow-path "$PWD/documents"Then pass the absolute path of a file in that directory in attachment_upload.source.path. The same object with a path field is accepted in message_send.attachments and question_answer.attachments. Over HTTP, use inline content or the ID of an attachment uploaded beforehand through the CLI or REST API.
Response progress
Read the current response state once with message_status. Follow progress with message_watch, using the same chatId and messageId. Replace the sample IDs below with the values from the accepted message.
{
"name": "message_watch",
"arguments": {
"chatId": "3f8b1a20-77c4-4c19-8d2e-1b9a4e6f0c85",
"messageId": "69de2470-09f4-43a1-a1dc-858ffad924a7",
"deadlineMs": 25000
},
"_meta": {
"progressToken": "response-1"
}
}When the client supplies _meta.progressToken, it receives notifications/progress. The message field contains the complete current response text with citations, or the execution state before text is available. Replace the displayed text with the new value on each update. Without a progressToken, the client receives the resulting structured snapshot when observation ends.
deadlineMs is a positive integer in milliseconds, with a default of 25000 and a maximum of 600000. Observation ends on completed, failed, stopped or waiting. Successful completion is confirmed by execution.state set to completed. After a WAIT_TIMEOUT error, call message_watch again with the same IDs; remote execution continues.
Cancelling a stdio call or closing a modern HTTP stream stops observation only. With older HTTP clients, observation may continue until its deadline. To stop the agent's work, call chat_stop with chatId and the specific messageId, then check the outcome with message_status.
Questions and workflows
The waiting state means the agent is waiting for a reply. Use interaction_list and interaction_get to read the question or workflow proposal, including its toolCallId and revision. Supply these values together with chatId and messageId when replying so that your response applies to the version you reviewed.
Answer a question with question_answer. Choices in selectedPositions are numbered from zero; supply text in freeText. You can attach files in the same way as when sending a message.
Decide on a workflow proposal with workflow_decide, setting decision to RUN, REQUEST_CHANGES or CANCEL. Include feedback for REQUEST_CHANGES. This decision applies to that proposal; use chat_stop to stop the entire execution.
Read workflow progress with workflow_list. Use subagent_list, subagent_get and subagent_message_list to inspect subagents and their messages. Read the main chat's history with chat_message_list and chat_message_get.