{"title":"Build a Custom MCP Client","slug":"custom-client","category":"mcp","summary":"Connect to the Synapse MCP server from your own application using the MCP SDK.","audience":["human","llm"],"tags":["mcp","custom","sdk","development"],"difficulty":"advanced","updated":"2026-06-27","word_count":157,"read_minutes":1,"lang":"en","translated":true,"requested_lang":"en","content_markdown":"\n# Build a Custom MCP Client\n\nIf you're building your own LLM application, you can connect to the Synapse\nMCP server directly using the official MCP SDK. This gives your app access to\nall 79 Synapse tools.\n\n## SDKs\n\n| Language | Package |\n|----------|---------|\n| TypeScript/JavaScript | `@modelcontextprotocol/sdk` |\n| Python | `mcp` |\n\n## TypeScript Example\n\n### Install\n\n```bash\nnpm install @modelcontextprotocol/sdk\n```\n\n### Connect via stdio\n\n```typescript\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\n\nconst transport = new StdioClientTransport({\n  command: \"npx\",\n  args: [\"-y\", \"synapse-mcp-api@latest\"],\n  env: {\n    SYNAPSE_MIND_KEY: process.env.SYNAPSE_MIND_KEY!,\n    SYNAPSE_URL: \"https://synapse.schaefer.zone\",\n  },\n});\n\nconst client = new Client(\n  { name: \"my-app\", version: \"1.0.0\" },\n  { capabilities: {} }\n);\n\nawait client.connect(transport);\n\n// List all available tools\nconst { tools } = await client.listTools();\nconsole.log(`Available tools: ${tools.length}`);\nfor (const tool of tools) {\n  console.log(`- ${tool.name}: ${tool.description}`);\n}\n\n// Call a tool\nconst result = await client.callTool({\n  name: \"memory_recall\",\n  arguments: {},\n});\nconsole.log(result.content);\n\n// Store a memory\nawait client.callTool({\n  name: \"memory_store\",\n  arguments: {\n    category: \"fact\",\n    key: \"custom_client_test\",\n    content: \"Built a custom MCP client\",\n    tags: [\"test\", \"mcp\"],\n    priority: \"normal\",\n  },\n});\n\nawait client.close();\n```\n\n### Connect via HTTP/SSE (remote)\n\n```typescript\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\n\nconst transport = new SSEClientTransport(\n  new URL(\"https://synapse-mcp.schaefer.zone/sse\"),\n  {\n    requestInit: {\n      headers: {\n        Authorization: `Bearer ${process.env.SYNAPSE_MIND_KEY}`,\n      },\n    },\n  }\n);\n\nconst client = new Client(\n  { name: \"my-app\", version: \"1.0.0\" },\n  { capabilities: {} }\n);\n\nawait client.connect(transport);\n// ... use as above\n```\n\n## Python Example\n\n### Install\n\n```bash\npip install mcp\n```\n\n### Connect via stdio\n\n```python\nfrom mcp import ClientSession, StdioServerParameters\nfrom mcp.client.stdio import stdio_client\n\nserver_params = StdioServerParameters(\n    command=\"npx\",\n    args=[\"-y\", \"synapse-mcp-api@latest\"],\n    env={\n        \"SYNAPSE_MIND_KEY\": \"mk_YOUR_KEY\",\n        \"SYNAPSE_URL\": \"https://synapse.schaefer.zone\",\n    },\n)\n\nasync with stdio_client(server_params) as (read, write):\n    async with ClientSession(read, write) as session:\n        await session.initialize()\n\n        # List tools\n        tools = await session.list_tools()\n        print(f\"Available tools: {len(tools.tools)}\")\n\n        # Call a tool\n        result = await session.call_tool(\"memory_recall\", {})\n        print(result.content)\n\n        # Store a memory\n        await session.call_tool(\"memory_store\", {\n            \"category\": \"fact\",\n            \"key\": \"python_client_test\",\n            \"content\": \"Built a Python MCP client\",\n            \"tags\": [\"test\", \"mcp\", \"python\"],\n            \"priority\": \"normal\",\n        })\n```\n\n## Tool Profiles\n\nWhen connecting, you can request a specific tool profile via the\n`Mcp-Tool-Profile` header (HTTP/SSE) or `MCP_PROFILE` env var (stdio):\n\n```typescript\n// stdio: set env var\nenv: {\n  SYNAPSE_MIND_KEY: \"mk_...\",\n  MCP_PROFILE: \"minimal\",  // 8 tools instead of 119\n}\n\n// HTTP/SSE: set header\nrequestInit: {\n  headers: {\n    Authorization: \"Bearer mk_...\",\n    \"Mcp-Tool-Profile\": \"minimal\",\n  },\n}\n```\n\n## Error Handling\n\n```typescript\ntry {\n  const result = await client.callTool({ name: \"memory_recall\", arguments: {} });\n  if (result.isError) {\n    console.error(\"Tool error:\", result.content);\n  } else {\n    console.log(\"Success:\", result.content);\n  }\n} catch (err) {\n  console.error(\"MCP error:\", err);\n}\n```\n\n## Use Cases\n\n- **Custom AI assistants** — build your own agent with persistent memory\n- **Workflow automation** — chain Synapse tools in custom workflows\n- **Data pipelines** — extract memories, transform, load elsewhere\n- **Monitoring dashboards** — display memory stats, chat history, tasks\n\n## Next Steps\n\n- [MCP Specification](https://spec.modelcontextprotocol.io)\n- [Synapse MCP Repo](https://gitlab.com/schaefer-services/synapse-mcp)\n- [API Overview](/docs/api/overview)\n","content_html":"<h1>Build a Custom MCP Client</h1>\n<p>If you&#39;re building your own LLM application, you can connect to the Synapse\nMCP server directly using the official MCP SDK. This gives your app access to\nall 79 Synapse tools.</p>\n<h2>SDKs</h2>\n<table>\n<thead>\n<tr>\n<th>Language</th>\n<th>Package</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>TypeScript/JavaScript</td>\n<td><code>@modelcontextprotocol/sdk</code></td>\n</tr>\n<tr>\n<td>Python</td>\n<td><code>mcp</code></td>\n</tr>\n</tbody></table>\n<h2>TypeScript Example</h2>\n<h3>Install</h3>\n<pre><code class=\"hljs language-bash\">npm install @modelcontextprotocol/sdk</code></pre><h3>Connect via stdio</h3>\n<pre><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">import</span> { <span class=\"hljs-title class_\">Client</span> } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">&quot;@modelcontextprotocol/sdk/client/index.js&quot;</span>;\n<span class=\"hljs-keyword\">import</span> { <span class=\"hljs-title class_\">StdioClientTransport</span> } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">&quot;@modelcontextprotocol/sdk/client/stdio.js&quot;</span>;\n\n<span class=\"hljs-keyword\">const</span> transport = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">StdioClientTransport</span>({\n  <span class=\"hljs-attr\">command</span>: <span class=\"hljs-string\">&quot;npx&quot;</span>,\n  <span class=\"hljs-attr\">args</span>: [<span class=\"hljs-string\">&quot;-y&quot;</span>, <span class=\"hljs-string\">&quot;synapse-mcp-api@latest&quot;</span>],\n  <span class=\"hljs-attr\">env</span>: {\n    <span class=\"hljs-attr\">SYNAPSE_MIND_KEY</span>: process.<span class=\"hljs-property\">env</span>.<span class=\"hljs-property\">SYNAPSE_MIND_KEY</span>!,\n    <span class=\"hljs-attr\">SYNAPSE_URL</span>: <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone&quot;</span>,\n  },\n});\n\n<span class=\"hljs-keyword\">const</span> client = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Client</span>(\n  { <span class=\"hljs-attr\">name</span>: <span class=\"hljs-string\">&quot;my-app&quot;</span>, <span class=\"hljs-attr\">version</span>: <span class=\"hljs-string\">&quot;1.0.0&quot;</span> },\n  { <span class=\"hljs-attr\">capabilities</span>: {} }\n);\n\n<span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">connect</span>(transport);\n\n<span class=\"hljs-comment\">// List all available tools</span>\n<span class=\"hljs-keyword\">const</span> { tools } = <span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">listTools</span>();\n<span class=\"hljs-variable language_\">console</span>.<span class=\"hljs-title function_\">log</span>(<span class=\"hljs-string\">`Available tools: <span class=\"hljs-subst\">${tools.length}</span>`</span>);\n<span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">const</span> tool <span class=\"hljs-keyword\">of</span> tools) {\n  <span class=\"hljs-variable language_\">console</span>.<span class=\"hljs-title function_\">log</span>(<span class=\"hljs-string\">`- <span class=\"hljs-subst\">${tool.name}</span>: <span class=\"hljs-subst\">${tool.description}</span>`</span>);\n}\n\n<span class=\"hljs-comment\">// Call a tool</span>\n<span class=\"hljs-keyword\">const</span> result = <span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">callTool</span>({\n  <span class=\"hljs-attr\">name</span>: <span class=\"hljs-string\">&quot;memory_recall&quot;</span>,\n  <span class=\"hljs-attr\">arguments</span>: {},\n});\n<span class=\"hljs-variable language_\">console</span>.<span class=\"hljs-title function_\">log</span>(result.<span class=\"hljs-property\">content</span>);\n\n<span class=\"hljs-comment\">// Store a memory</span>\n<span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">callTool</span>({\n  <span class=\"hljs-attr\">name</span>: <span class=\"hljs-string\">&quot;memory_store&quot;</span>,\n  <span class=\"hljs-attr\">arguments</span>: {\n    <span class=\"hljs-attr\">category</span>: <span class=\"hljs-string\">&quot;fact&quot;</span>,\n    <span class=\"hljs-attr\">key</span>: <span class=\"hljs-string\">&quot;custom_client_test&quot;</span>,\n    <span class=\"hljs-attr\">content</span>: <span class=\"hljs-string\">&quot;Built a custom MCP client&quot;</span>,\n    <span class=\"hljs-attr\">tags</span>: [<span class=\"hljs-string\">&quot;test&quot;</span>, <span class=\"hljs-string\">&quot;mcp&quot;</span>],\n    <span class=\"hljs-attr\">priority</span>: <span class=\"hljs-string\">&quot;normal&quot;</span>,\n  },\n});\n\n<span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">close</span>();</code></pre><h3>Connect via HTTP/SSE (remote)</h3>\n<pre><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">import</span> { <span class=\"hljs-title class_\">Client</span> } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">&quot;@modelcontextprotocol/sdk/client/index.js&quot;</span>;\n<span class=\"hljs-keyword\">import</span> { <span class=\"hljs-title class_\">SSEClientTransport</span> } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">&quot;@modelcontextprotocol/sdk/client/sse.js&quot;</span>;\n\n<span class=\"hljs-keyword\">const</span> transport = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">SSEClientTransport</span>(\n  <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title function_\">URL</span>(<span class=\"hljs-string\">&quot;https://synapse-mcp.schaefer.zone/sse&quot;</span>),\n  {\n    <span class=\"hljs-attr\">requestInit</span>: {\n      <span class=\"hljs-attr\">headers</span>: {\n        <span class=\"hljs-title class_\">Authorization</span>: <span class=\"hljs-string\">`Bearer <span class=\"hljs-subst\">${process.env.SYNAPSE_MIND_KEY}</span>`</span>,\n      },\n    },\n  }\n);\n\n<span class=\"hljs-keyword\">const</span> client = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-title class_\">Client</span>(\n  { <span class=\"hljs-attr\">name</span>: <span class=\"hljs-string\">&quot;my-app&quot;</span>, <span class=\"hljs-attr\">version</span>: <span class=\"hljs-string\">&quot;1.0.0&quot;</span> },\n  { <span class=\"hljs-attr\">capabilities</span>: {} }\n);\n\n<span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">connect</span>(transport);\n<span class=\"hljs-comment\">// ... use as above</span></code></pre><h2>Python Example</h2>\n<h3>Install</h3>\n<pre><code class=\"hljs language-bash\">pip install mcp</code></pre><h3>Connect via stdio</h3>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from</span> mcp <span class=\"hljs-keyword\">import</span> ClientSession, StdioServerParameters\n<span class=\"hljs-keyword\">from</span> mcp.client.stdio <span class=\"hljs-keyword\">import</span> stdio_client\n\nserver_params = StdioServerParameters(\n    command=<span class=\"hljs-string\">&quot;npx&quot;</span>,\n    args=[<span class=\"hljs-string\">&quot;-y&quot;</span>, <span class=\"hljs-string\">&quot;synapse-mcp-api@latest&quot;</span>],\n    env={\n        <span class=\"hljs-string\">&quot;SYNAPSE_MIND_KEY&quot;</span>: <span class=\"hljs-string\">&quot;mk_YOUR_KEY&quot;</span>,\n        <span class=\"hljs-string\">&quot;SYNAPSE_URL&quot;</span>: <span class=\"hljs-string\">&quot;https://synapse.schaefer.zone&quot;</span>,\n    },\n)\n\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">with</span> stdio_client(server_params) <span class=\"hljs-keyword\">as</span> (read, write):\n    <span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">with</span> ClientSession(read, write) <span class=\"hljs-keyword\">as</span> session:\n        <span class=\"hljs-keyword\">await</span> session.initialize()\n\n        <span class=\"hljs-comment\"># List tools</span>\n        tools = <span class=\"hljs-keyword\">await</span> session.list_tools()\n        <span class=\"hljs-built_in\">print</span>(<span class=\"hljs-string\">f&quot;Available tools: <span class=\"hljs-subst\">{<span class=\"hljs-built_in\">len</span>(tools.tools)}</span>&quot;</span>)\n\n        <span class=\"hljs-comment\"># Call a tool</span>\n        result = <span class=\"hljs-keyword\">await</span> session.call_tool(<span class=\"hljs-string\">&quot;memory_recall&quot;</span>, {})\n        <span class=\"hljs-built_in\">print</span>(result.content)\n\n        <span class=\"hljs-comment\"># Store a memory</span>\n        <span class=\"hljs-keyword\">await</span> session.call_tool(<span class=\"hljs-string\">&quot;memory_store&quot;</span>, {\n            <span class=\"hljs-string\">&quot;category&quot;</span>: <span class=\"hljs-string\">&quot;fact&quot;</span>,\n            <span class=\"hljs-string\">&quot;key&quot;</span>: <span class=\"hljs-string\">&quot;python_client_test&quot;</span>,\n            <span class=\"hljs-string\">&quot;content&quot;</span>: <span class=\"hljs-string\">&quot;Built a Python MCP client&quot;</span>,\n            <span class=\"hljs-string\">&quot;tags&quot;</span>: [<span class=\"hljs-string\">&quot;test&quot;</span>, <span class=\"hljs-string\">&quot;mcp&quot;</span>, <span class=\"hljs-string\">&quot;python&quot;</span>],\n            <span class=\"hljs-string\">&quot;priority&quot;</span>: <span class=\"hljs-string\">&quot;normal&quot;</span>,\n        })</code></pre><h2>Tool Profiles</h2>\n<p>When connecting, you can request a specific tool profile via the\n<code>Mcp-Tool-Profile</code> header (HTTP/SSE) or <code>MCP_PROFILE</code> env var (stdio):</p>\n<pre><code class=\"hljs language-typescript\"><span class=\"hljs-comment\">// stdio: set env var</span>\n<span class=\"hljs-attr\">env</span>: {\n  <span class=\"hljs-attr\">SYNAPSE_MIND_KEY</span>: <span class=\"hljs-string\">&quot;mk_...&quot;</span>,\n  <span class=\"hljs-attr\">MCP_PROFILE</span>: <span class=\"hljs-string\">&quot;minimal&quot;</span>,  <span class=\"hljs-comment\">// 8 tools instead of 119</span>\n}\n\n<span class=\"hljs-comment\">// HTTP/SSE: set header</span>\n<span class=\"hljs-attr\">requestInit</span>: {\n  <span class=\"hljs-attr\">headers</span>: {\n    <span class=\"hljs-title class_\">Authorization</span>: <span class=\"hljs-string\">&quot;Bearer mk_...&quot;</span>,\n    <span class=\"hljs-string\">&quot;Mcp-Tool-Profile&quot;</span>: <span class=\"hljs-string\">&quot;minimal&quot;</span>,\n  },\n}</code></pre><h2>Error Handling</h2>\n<pre><code class=\"hljs language-typescript\"><span class=\"hljs-keyword\">try</span> {\n  <span class=\"hljs-keyword\">const</span> result = <span class=\"hljs-keyword\">await</span> client.<span class=\"hljs-title function_\">callTool</span>({ <span class=\"hljs-attr\">name</span>: <span class=\"hljs-string\">&quot;memory_recall&quot;</span>, <span class=\"hljs-attr\">arguments</span>: {} });\n  <span class=\"hljs-keyword\">if</span> (result.<span class=\"hljs-property\">isError</span>) {\n    <span class=\"hljs-variable language_\">console</span>.<span class=\"hljs-title function_\">error</span>(<span class=\"hljs-string\">&quot;Tool error:&quot;</span>, result.<span class=\"hljs-property\">content</span>);\n  } <span class=\"hljs-keyword\">else</span> {\n    <span class=\"hljs-variable language_\">console</span>.<span class=\"hljs-title function_\">log</span>(<span class=\"hljs-string\">&quot;Success:&quot;</span>, result.<span class=\"hljs-property\">content</span>);\n  }\n} <span class=\"hljs-keyword\">catch</span> (err) {\n  <span class=\"hljs-variable language_\">console</span>.<span class=\"hljs-title function_\">error</span>(<span class=\"hljs-string\">&quot;MCP error:&quot;</span>, err);\n}</code></pre><h2>Use Cases</h2>\n<ul>\n<li><strong>Custom AI assistants</strong> — build your own agent with persistent memory</li>\n<li><strong>Workflow automation</strong> — chain Synapse tools in custom workflows</li>\n<li><strong>Data pipelines</strong> — extract memories, transform, load elsewhere</li>\n<li><strong>Monitoring dashboards</strong> — display memory stats, chat history, tasks</li>\n</ul>\n<h2>Next Steps</h2>\n<ul>\n<li><a href=\"https://spec.modelcontextprotocol.io\">MCP Specification</a></li>\n<li><a href=\"https://gitlab.com/schaefer-services/synapse-mcp\">Synapse MCP Repo</a></li>\n<li><a href=\"/docs/api/overview\">API Overview</a></li>\n</ul>\n","urls":{"html":"/docs/mcp/custom-client","text":"/docs/mcp/custom-client?format=text","json":"/docs/mcp/custom-client?format=json","llm":"/docs/mcp/custom-client?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}