claude code 安くて便利。
自前 MCP を大量に持ってると、手元に用意しておいた MCP サーバーに繋ぎたくなります。
以下のドキュメントによると、 claude --mcp-config=...
でローカルな MCP サーバーを叩けるみたいです。
以下、claude code に手元の MCP サーバーを登録する例です。
ローカル MCP につなぐ
MCP サーバー実装を書きます。
これは指定した URL を本文抽出して markdown で取得する実装です。
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { extract, toMarkdown } from "@mizchi/readability";
const server = new McpServer({
name: "deno",
version: "1.0.0",
});
server.tool(
"read_url_content",
"与えられたURLの本文抽出で取得し、Markdown形式で返します。",
{ url: z.string().describe("URL") },
async ({ url }) => {
const html = await fetch(url).then((res) => res.text());
const extracted = extract(html, { charThreshold: 100 });
if (extracted.root) {
const parsed = toMarkdown(extracted.root);
return { content: [{ type: "text", text: parsed }] };
} else {
return {
content: [
{
type: "text",
text: `No content found at the provided URL. Return full html.\n${html}`,
},
],
};
}
}
);
try {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Local MCP Server running on stdio");
} catch (error) {
console.error("Error starting MCP server:", error);
process.exit(1);
}
特に変なことはしていません。
実行
これを標準入出力で読み込む設定の例
.claude/mcp.json
{
"mcpServers": {
"local": {
"command": "node",
"args": [".claude/mcp-server.ts"]
}
}
}
これは次のように読み込みます。
$ claude --mcp-config=.claude/mcp.json
実行例
> https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling を markdown で要約して
Tool use │
│ │
│ local:read_url_content(url: "https://ai-sdk.dev/doc │
│ s/ai-sdk-core/tools-and-tool-calling") (MCP) │
│ 与えられたURLの本文抽出で取得し、Markdown形式で返し │
│ ます。 │
│ │
│ Do you want to proceed? │
│ ❯ 1. Yes │
│ 2. Yes, and don't ask again for local:read_url_content │
│ commands in /home/mizchi/sandbox/claude-mcp │
│ │
│ 3. No, and tell Claude what to do differently
使用例
import { generateText, tool } from 'ai';
import { z } from 'zod';
const result = await generateText({
model: yourModel,
tools: {
weather: tool({
description: '場所の天気を取得',
parameters: z.object({
location:
z.string().describe('天気を取得する場所'),
}),
execute: async ({ location }) => ({
location,
temperature: 72 + Math.floor(Math.random() *
21) - 10,
}),
}),
},
maxSteps: 5,
toolChoice: 'required',
prompt: 'サンフランシスコの天気は?',
});
おまけ: deno 用
MCP サーバーはパーミッションを絞って起動したいので、自分は deno で書いてることが多いです。
サーバー実装は実装は node 互換モードでだいたい一緒なので略。
コマンド部分に deno run -A --deny-env
相当を渡します。
.claude/mcp.json
{
"mcpServers": {
"deno-local": {
"command": "deno",
"args": ["run", "-A", "--deny-env", ".claude/deno-server.ts"]
}
}
}
node 環境でも .vscode/settings.json
のdeno.enablePaths
で .claude/deno-server.ts
だけ Deno LSP を有効にします。
.vscode/settings.json
{
"deno.enablePaths": [".claude/deno-server.ts"]
}
おまけ: zshrc 用の claudex コマンド
.claude/mcp.json
がある場合、これを読み込むコマンドを作りました。
function claudex() {
git_root=$(git rev-parse --show-toplevel 2>/dev/null)
if [ -f "$git_root/.claude/mcp.json" ]; then
claude --mcp-config="$git_root/.claude/mcp.json" "$@"
else
claude "$@"
fi
}
Views: 0