How to Configure MCP Server Sources with JSON Schemas and Custom Endpoints in Craft Agents
Craft Agents configures MCP (Model Context Protocol) server sources through JSON files in ~/.craft-agent/workspaces/<workspace-id>/sources/<source-slug>/config.json, using the McpSourceConfig schema defined in packages/shared/src/sources/types.ts to support HTTP, SSE, and stdio transports with customizable endpoints and authentication.
Craft Agents treats every external data connection as a source, with MCP servers representing a critical integration pattern for document-based AI workflows. Understanding how to configure MCP server sources with JSON schemas and custom endpoints allows you to connect remote HTTP endpoints, local subprocesses, or custom protocol implementations to your agent workspace. The configuration schema is defined in the craft-ai-agents/craft-agents-oss repository and processed by the SourceServerBuilder class to instantiate running server connections.
MCP Source Configuration Schema
The JSON schema for MCP sources is defined in packages/shared/src/sources/types.ts within the McpSourceConfig interface (lines 50-98). Each source configuration resides in a config.json file located at ~/.craft-agent/workspaces/<workspace-id>/sources/<source-slug>/.
Core Configuration Fields
The mcp object within your configuration must specify transport type and endpoint details:
- transport:
'http','sse', or'stdio'— determines how the server is reached - url: Required for HTTP/SSE transports; the exact endpoint URL (default: none)
- command: Required for stdio transport; the executable to spawn
- args: Optional array of arguments for stdio commands
- env: Optional environment variables for stdio processes
- authType:
'oauth','bearer', or'none'— authentication method (default:'none') - clientId: OAuth client identifier (stored in config, not the secret vault)
- headers: Static request headers sent with every request
- headerNames: Array of secret header names stored in the credential vault (e.g.,
"X-API-Key")
Configuring HTTP and SSE Transport Endpoints
For remote MCP servers accessible via HTTP or Server-Sent Events (SSE), the configuration requires a valid url and optional authentication parameters.
{
"id": "my-mcp",
"name": "My Custom MCP",
"slug": "my-mcp",
"enabled": true,
"provider": "custom-mcp",
"type": "mcp",
"mcp": {
"transport": "http",
"url": "https://my-mcp.example.com/api/v2",
"authType": "bearer",
"headerNames": ["X-API-Key"]
},
"icon": "🛠️"
}
When processing this configuration, SourceServerBuilder.buildMcpServer validates that url is present, applies normalizeMcpUrl (lines 71-78 in packages/shared/src/sources/server-builder.ts), and merges headers in three precedence layers: static headers, secret headerNames from the credential store, and an Authorization: Bearer <token> header when authType is not 'none'.
Configuring Stdio Transport for Local MCP Servers
For locally-running MCP servers implemented as scripts or compiled binaries, use the stdio transport which spawns a subprocess rather than connecting to a remote URL.
{
"id": "local-mcp",
"name": "Local MCP",
"slug": "local-mcp",
"enabled": true,
"provider": "local-mcp",
"type": "mcp",
"mcp": {
"transport": "stdio",
"command": "python",
"args": ["-m", "my_mcp_server"],
"env": {
"PORT": "8080"
}
}
}
No URL or authentication headers are required for stdio transport because the process runs locally. The builder expects the command field and optionally args and env to configure the execution environment.
How the Server Builder Processes Your Configuration
When the application initializes, SourceServerBuilder.buildMcpServer (implemented in packages/shared/src/sources/server-builder.ts lines 86-115) transforms your JSON configuration into a runnable server configuration used by the Claude Agent SDK.
The build process follows this sequence:
- Load the source configuration via
loadSourcefrompackages/shared/src/sources/storage.ts - Normalize the URL using
normalizeMcpUrlto ensure proper formatting - Validate required fields for the specified transport type
- Merge authentication headers and credential vault secrets
- Return a server configuration object or
nullif validation fails
If required fields are missing, the builder logs a debug message and returns null, causing the UI to surface an "Authentication required" error (lines 124-138).
Custom Endpoint Configuration
You can point to any MCP-compatible endpoint by setting the url field to your specific path. The builder does not append any path suffix; it uses the URL exactly as provided, enabling connections to sandbox environments, version-specific API endpoints, or proxied services.
// How the builder turns config into a server config
import { getSourceServerBuilder } '@/shared/src/sources/server-builder.ts';
import { loadSource } from '@/shared/src/sources/storage.ts';
async function demo() {
const source = await loadSource('my-workspace', 'my-mcp');
const token = 'eyJhbGciOi...'; // obtained via OAuth flow
const builder = getSourceServerBuilder();
const mcpServer = builder.buildMcpServer(source, token);
console.log(mcpServer);
/*
{
type: 'http',
url: 'https://my-mcp.example.com/api/v2',
headers: {
'X-API-Key': '<secret-from-vault>',
Authorization: 'Bearer eyJhbGciOi...'
}
}
*/
}
Authentication and Header Management
Authentication headers are merged in three layers with distinct precedence:
- Static headers — Defined directly in the
headersfield of the configuration - Secret headers — Referenced by name in
headerNames, fetched from the credential vault at runtime - Authorization header — Automatically added when
authTypeis'bearer'or'oauth'
This layering allows you to combine public configuration values with sensitive credentials stored securely outside the JSON file.
Summary
- Craft Agents stores MCP source configurations in
~/.craft-agent/workspaces/<workspace-id>/sources/<source-slug>/config.json - The
McpSourceConfiginterface inpackages/shared/src/sources/types.tsdefines the complete JSON schema - Three transport types are supported:
http,sse, andstdio - Custom endpoints are configured by setting the exact URL in the
urlfield without path modification by the builder SourceServerBuilder.buildMcpServerprocesses configurations throughnormalizeMcpUrland validates required fields per transport type- Authentication supports OAuth, Bearer tokens, and static headers with credential vault integration via
headerNames
Frequently Asked Questions
Where is the MCP source configuration stored in Craft Agents?
Each MCP source configuration is stored as a config.json file inside ~/.craft-agent/workspaces/<workspace-id>/sources/<source-slug>/. The JSON schema is strictly defined by the McpSourceConfig interface in packages/shared/src/sources/types.ts, which the system validates before attempting to establish connections.
What transport types are supported for MCP server sources?
Craft Agents supports three transport types: http for standard HTTP requests, sse for Server-Sent Events connections, and stdio for local subprocess execution. HTTP and SSE transports require a url field, while stdio transport requires a command field specifying the executable to spawn.
How does authentication work for MCP server sources?
Authentication is configured via the authType field accepting values of oauth, bearer, or none. For HTTP/SSE transports, the builder automatically adds an Authorization: Bearer <token> header when authType is not none. Secret headers referenced in headerNames are retrieved from the credential vault and merged with static headers defined in the configuration.
Can I use custom URL paths or versioned endpoints for my MCP server?
Yes. The url field accepts any valid URL pointing to an MCP protocol endpoint. According to the source code in packages/shared/src/sources/server-builder.ts, the SourceServerBuilder uses the URL exactly as provided without appending suffixes, allowing you to specify versioned endpoints (e.g., /api/v2), sandbox URLs, or custom paths.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →