# How to Configure MCP Server Sources with JSON Schemas and Custom Endpoints in Craft Agents

> Configure MCP server sources in Craft Agents using JSON schemas and custom endpoints. Learn to set up HTTP, SSE, and stdio transports with flexible authentication for your agents.

- Repository: [Craft Ai Agents/craft-agents-oss](https://github.com/craft-ai-agents/craft-agents-oss)
- Tags: how-to-guide
- Published: 2026-07-03

---

**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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/sources/types.ts)** within the `McpSourceConfig` interface (lines 50-98). Each source configuration resides in a [`config.json`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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.

```json
{
  "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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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.

```json
{
  "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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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:

1. **Load** the source configuration via `loadSource` from [`packages/shared/src/sources/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/sources/storage.ts)
2. **Normalize** the URL using `normalizeMcpUrl` to ensure proper formatting
3. **Validate** required fields for the specified transport type
4. **Merge** authentication headers and credential vault secrets
5. **Return** a server configuration object or `null` if 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.

```typescript
// 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:

1. **Static headers** — Defined directly in the `headers` field of the configuration
2. **Secret headers** — Referenced by name in `headerNames`, fetched from the credential vault at runtime
3. **Authorization header** — Automatically added when `authType` is `'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 **`McpSourceConfig`** interface in [`packages/shared/src/sources/types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/sources/types.ts) defines the complete JSON schema
- Three transport types are supported: **`http`**, **`sse`**, and **`stdio`**
- Custom endpoints are configured by setting the exact URL in the `url` field without path modification by the builder
- **`SourceServerBuilder.buildMcpServer`** processes configurations through `normalizeMcpUrl` and 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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/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.