This document describes the MCP implementation that is currently in this repository.
2025-11-25 with fallback negotiation to 2025-03-26 and 2024-11-05.stdio and HTTP (POST with JSON or SSE responses).hlvm mcp add/list/remove/login/logout and REPL /mcp.http://127.0.0.1:35017/hlvm/oauth/callback with success page.8 interop tests (conformance handled by MCP SDK).hlvm ask with no extra per-request auth steps.Pick one launcher style:
hlvmdeno run -A src/hlvm/cli/cli.tsA convenient alias:
HLVM_CMD='deno run -A src/hlvm/cli/cli.ts'
# or: HLVM_CMD='hlvm'
NAME="<server_name>"; URL="<mcp_http_url>"; $HLVM_CMD mcp add "$NAME" --url "$URL" && $HLVM_CMD mcp login "$NAME"
Example:
NAME="notion"; URL="https://mcp.notion.com/mcp"; $HLVM_CMD mcp add "$NAME" --url "$URL" && $HLVM_CMD mcp login "$NAME"
$HLVM_CMD mcp add github -- npx -y @modelcontextprotocol/server-github
$HLVM_CMD mcp list
$HLVM_CMD ask "use my MCP tools"
hlvm mcp login <name> does the following:
S256) and opens browser.127.0.0.1:35017.Token storage:
~/.hlvm/mcp-oauth.jsonHLVM_MCP_OAUTH_PATHRuntime behavior:
Authorization header automatically when token exists.401 with Bearer challenge, tries refresh and retries once.Run: hlvm mcp login <name>HLVM loads config from three scopes, highest priority first:
<workspace>/.mcp.json<workspace>/.hlvm/mcp.json~/.hlvm/mcp.jsonIf names collide, first match wins (higher-priority scope overrides lower).
.mcp.json format (Claude Code style){
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "..." }
},
"notion": {
"url": "https://mcp.notion.com/mcp"
}
}
}
.hlvm/mcp.json and ~/.hlvm/mcp.json){
"version": 1,
"servers": [
{
"name": "github",
"command": ["npx", "-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "..." }
},
{
"name": "notion",
"url": "https://mcp.notion.com/mcp"
}
]
}
hlvm mcp add <name> -- <command...>
hlvm mcp add <name> --url <url>
hlvm mcp list
hlvm mcp remove <name> [--scope project|user]
hlvm mcp login <name>
hlvm mcp logout <name>
Notes:
add --scope project|user (default: project)add --env KEY=VALUE repeatableremove without scope tries project first, then user.mcp.json entries are file-managed; remove them by editing .mcp.json/mcp lists configured MCP servers with transport and scope labels.
At session startup, MCP tools are loaded and registered. Connected servers are logged:
MCP: <server> — <toolCount> toolsTool naming pattern:
mcp_<server>_<tool>Resource and prompt helpers are auto-registered when capability exists:
mcp_<server>_list_resourcesmcp_<server>_read_resourcemcp_<server>_list_promptsmcp_<server>_get_prompttools/list, tools/call)list/read/templates/subscribe/unsubscribe)list/get)sampling/createMessage)elicitation/create)roots/list)completion/complete)logging/setLevel, notifications/message)notifications/cancelled)notifications/progress)These are intentionally explicit so docs match implementation reality:
409 session recreation.tests/interop/mcp/ (8 tests against @modelcontextprotocol/server-everything)tests/unit/agent/mcp-oauth.test.tstests/unit/agent/mcp.test.tsRun commands:
deno task test:conformance # interop tests
deno test --allow-all tests/unit/agent/mcp-oauth.test.ts
deno test --allow-all tests/unit/agent/mcp.test.ts
Recent live verification against Notion MCP in this environment:
127.0.0.1:35017.initialize HTTP status 200tools/list HTTP status 20012mcp login is running in terminal while approving OAuth.invalid_grant during loginClient ID mismatchmcp login and complete once end-to-end.NO_TOKEN after loginhlvm mcp list and ensure server name matches what you logged in with.~/.hlvm/mcp-oauth.json exists and contains that server key.401 on MCP callhlvm mcp login <name> again.src/hlvm/agent/mcp/sdk-client.tssrc/hlvm/agent/mcp/oauth.tssrc/hlvm/agent/mcp/config.tssrc/hlvm/agent/mcp/tools.tssrc/hlvm/agent/mcp/types.tssrc/hlvm/agent/mcp/mod.tssrc/hlvm/cli/commands/mcp.tssrc/hlvm/cli/repl/commands.ts