# MCP (Model Context Protocol) Steward can connect to remote **MCP servers** and expose their tools in agent conversations. Each server is defined as a markdown note under `Steward/MCP/`. The model receives **active** tools (the ones you list on the conversation) as dynamic calls; other discovered tools stay **inactive** until you add them. ## How it works 1. You add a `.md` file in `Steward/MCP/` with YAML frontmatter and a fenced JSON block that describes how to reach the server (transport and URL). 2. Steward loads the note when the vault layout is ready and keeps it in sync when the file is created, modified, or deleted. 3. A **status** field in frontmatter is maintained automatically (valid vs invalid config). 4. At runtime, Steward connects to each enabled definition with valid config, discovers tools, and prefixes their names so they are unique across servers. ## Definition note format Place each server in its own file, for example `Steward/MCP/My fetch server.md`. ### Frontmatter | Field | Required | Description | | ------------- | -------- | ---------------------------------------------------------------------------------------------------------- | | `name` | No | Display name; defaults to the note’s basename | | `description` | No | Short description | | `enabled` | No | If omitted, Steward writes `enabled: true` when it updates the note. Set to `false` to disable this server | | `status` | No | Auto-updated: reflects whether the JSON config is valid | The markdown **body** (outside the JSON block) is optional instructional text for the note; it is not required for the connection itself. ### JSON config block Include exactly one fenced `json` block with the server connection settings: | Field | Required | Description | | ----------- | -------- | ------------------------------------------------------------------------------- | | `transport` | Yes | `http` or `sse` | | `url` | Yes | MCP endpoint URL (non-empty) | | `headers` | No | Optional map of header names to string values | | `enabled` | No | Defaults to `true`. You can set `false` to disable the server from config alone | ### Secrets in config You can reference Obsidian **secrets** inside string values with: `$secret:your-secret-key` Obsidian Secrets settings: search field and a secret entry using a hyphenated name Steward resolves the name against the vault’s secret storage. If a name is missing, the placeholder is left as-is and a warning is logged. `your-secret-key` is an example Obsidian secret name—use your real secret’s name from Obsidian’s Secrets settings in the placeholder. ### Example Frontmatter and optional body text: ```yaml --- name: Example MCP description: Search and fetch tools --- # Example MCP ``` JSON block (use a single fenced `json` code block in the same note, after the body text): ```json { "transport": "http", "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer $secret:example-api-token" } } ``` ## Which tools run in a conversation? Conversation notes support a **`tools`** frontmatter key: an array of tool name strings. - Tools **listed** there are treated as **active** for that conversation (passed for dynamic invocation). - Tools **not** listed remain **inactive** for that conversation. Tool names are prefixed as: `mcp__{serverId}__{toolNameFromServer}` `serverId` is derived from the definition note’s basename (normalized to a stable lowercase id). Definitions that are disabled, have invalid or missing config, or fail to connect do not contribute tools to either list. ## Troubleshooting - **Invalid status** — Open the MCP file and fix the JSON block until `status` shows valid. Check `transport`, `url`, and optional `headers`. - **Connection failures** — Confirm the URL is reachable and credentials in `$secret:...` exist in Obsidian’s secret settings. - **Tool not available** — Add the full prefixed tool name to the conversation note’s `tools` frontmatter array for it to be active.