Capman
БесплатноНе проверенExposes capman capability manifests as typed, governed MCP tools for use with Claude Desktop or any MCP-compatible client, with approval, privacy, and risk filt
Описание
Exposes capman capability manifests as typed, governed MCP tools for use with Claude Desktop or any MCP-compatible client, with approval, privacy, and risk filtering.
README
MCP (Model Context Protocol) adapter for capman — exposes a capman capability manifest as a typed, governed set of MCP tools callable by Claude Desktop, the Claude API, or any MCP-compatible client.
Version: 0.1.0 · Node.js: ≥ 18 · capman peer: ≥ 0.6.3 · License: MIT
Table of Contents
- Overview
- Architecture
- Installation
- Quick start — Claude Desktop
- Demo mode
- Operating modes
- Config reference
- Capability filtering
- Policy gate and risk levels
- Registry
- Dependency graph
- Catalog service
- Matching modes
- Verdict handling
- Audit log
- HTTP transport
- Troubleshooting
Overview
capman-mcp sits between your capman manifest and any MCP client. It reads your manifest,
applies a governance layer (approval, privacy, risk), and exposes each approved capability
as a typed MCP tool. Every tool call is translated into engine.ask(), the result is
validated, logged, and returned as a structured MCP response.
MCP client (Claude Desktop / API)
│ tools/list + tools/call (MCP protocol)
▼
capman-mcp
├── Approval gate (allowlist or registry)
├── Privacy filter (public only)
├── Risk gate (policyGate — blocks high-risk by default)
├── Dependency graph (cycle detection + impact analysis)
└── Catalog service (read-only HTTP discovery API)
│ engine.ask()
▼
capman (BM25 → LLM → resolve → HTTP)
│
▼
Your app's REST API
Architecture
capman-mcp is composed of six independent layers, each in its own module:
| Module | Responsibility |
|---|---|
bridge.ts |
Converts manifest capabilities to MCP tool definitions; applies all filters |
allowlist.ts |
Loads config; validates allowed capability IDs |
server.ts |
MCP server bootstrap; callTool handler; demo mode |
logger.ts |
Append-only audit log; JSON (production) or human-readable (demo) |
registry.ts |
Persistent capability registry; publish, deprecate, diff |
risk.ts |
Pure risk level derivation from HTTP method, privacy, and error codes |
graph.ts |
Dependency graph; cycle detection; impact analysis |
catalog.ts |
Read-only HTTP catalog service |
resolve.ts |
resolveById — registry-mode bypass of the matcher |
schema-derive.ts |
Input/output schema derivation from capability definitions |
output-validate.ts |
Runtime validation of engine results against declared output schemas |
Installation
npm install capman-mcp capman
capman is a peer dependency. Install it alongside capman-mcp so you control the version.
Quick start — Claude Desktop
1. Generate your manifest
# From an existing OpenAPI spec
npx capman generate --from openapi.json
# Or from a capman.config.js you wrote
npx capman generate
This produces capman.manifest.json in your working directory.
2. Create capman-mcp.config.js
// capman-mcp.config.js
module.exports = {
manifest: '/absolute/path/to/capman.manifest.json',
baseUrl: 'https://api.your-app.com',
mode: 'balanced',
dryRun: false,
transport: 'stdio',
allowedCapabilities: [
{ id: 'get_order' },
{ id: 'list_products' },
{ id: 'check_availability' },
],
audit: {
enabled: true,
logFile: '.capman/mcp-audit.log',
},
}
Always use absolute paths. Claude Desktop resolves paths from its own working directory, not yours. Relative paths will silently fail to load.
3. Add capman-mcp to Claude Desktop
Open your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add a new entry under mcpServers:
{
"mcpServers": {
"my-app": {
"command": "npx",
"args": [
"capman-mcp",
"start",
"--config",
"/absolute/path/to/capman-mcp.config.js"
]
}
}
}
4. Test before connecting
Run the server manually first to confirm the config loads cleanly:
npx capman-mcp start --config /absolute/path/to/capman-mcp.config.js
Expected output:
[capman-mcp] Loaded manifest: your-app (12 capabilities)
[capman-mcp] 8 tools registered
[capman-mcp] MCP server running on stdio
5. Restart Claude Desktop
Quit Claude Desktop completely and reopen it. Your capabilities are now available as tools.
Demo mode
Try capman-mcp with a bundled sample manifest — no real app, no config, no API keys:
npx capman-mcp demo
This starts a dryRun: true server with 4 sample e-commerce capabilities. To connect
Claude Desktop, add this to claude_desktop_config.json:
{
"mcpServers": {
"capman-demo": {
"command": "npx",
"args": ["capman-mcp", "demo"]
}
}
}
Then restart Claude Desktop and ask: "get order ORD-123" or "list products".
Operating modes
capman-mcp supports two approval modes. Choose one per deployment.
Config mode (default)
The allowedCapabilities array in your config file is the source of truth for which
capabilities are exposed. Straightforward for single-service or single-team setups.
allowedCapabilities: [
{ id: 'get_order' },
{ id: 'list_products', descriptionOverride: 'Browse the product catalog' },
{ id: 'delete_account', allowHighRisk: true },
]
Registry mode
Set registryPath to enable registry-based approval. Approval state, risk level,
dependency declarations, and deprecation are all stored in a versioned JSON registry
file. Intended for teams where a CI pipeline publishes capabilities and a separate
approval step gates MCP exposure.
module.exports = {
manifest: '/path/to/capman.manifest.json',
registryPath: '/path/to/.capman-mcp/registry.json',
transport: 'stdio',
// allowedCapabilities can still be used for descriptionOverride / dryRunOverride
allowedCapabilities: [],
}
In registry mode, resolveById is used instead of engine.ask() — the tool name
directly identifies the capability, bypassing the matcher entirely for lower latency.
Config reference
CapmanMcpConfig
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
manifest |
string |
✅ | — | Absolute path to capman.manifest.json |
baseUrl |
string |
— | — | Base URL for API resolvers |
mode |
'cheap' | 'balanced' | 'accurate' |
— | 'balanced' |
Matching mode (config mode only) |
dryRun |
boolean |
— | false |
Plan API calls without executing them |
transport |
'stdio' | 'http' |
— | 'stdio' |
MCP transport |
httpPort |
number |
— | 3000 |
Port when transport: 'http' |
allowedCapabilities |
AllowedCapabilityEntry[] |
✅* | — | *Required in config mode; optional override layer in registry mode |
registryPath |
string |
— | — | Enables registry mode when set |
policyGate |
boolean |
— | true |
Block high-risk capabilities unless explicitly opted in |
auth |
CapmanMcpAuthConfig |
— | — | Auth context for the server instance. Required to expose user_owned capabilities |
audit.enabled |
boolean |
— | true |
Enable invocation logging |
audit.logFile |
string |
— | stderr | Append-only audit log path |
AllowedCapabilityEntry
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
✅ | Capability ID from your manifest |
descriptionOverride |
string |
— | Replaces the capability description shown in the MCP tool listing |
dryRunOverride |
boolean |
— | Per-capability dry-run — takes precedence over global dryRun |
allowHighRisk |
boolean |
— | Explicitly expose this capability despite a high risk level |
CapmanMcpAuthConfig
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
isAuthenticated |
boolean |
✅ | — | Must be true for user_owned capabilities to be exposed and executed |
userId |
string |
— | — | Injected by capman into params marked source: 'session'. Never exposed to the agent |
role |
'user' | 'admin' |
— | 'user' |
User's role. admin capabilities remain hard-blocked regardless of this value |
Capability filtering
buildToolList applies four filters in order before exposing a capability as an MCP tool.
A capability must pass all four to appear.
| Filter | Condition to pass | Notes |
|---|---|---|
| 1. Approval | In allowedCapabilities (config mode) or approvedForMcp: true in registry |
|
| 2. Privacy | privacy.level === 'public' |
user_owned and admin require auth context MCP cannot provide |
| 3. Lifecycle | lifecycle.status !== 'deprecated' |
Deprecated capabilities are never surfaced |
| 4. Risk gate | riskLevel !== 'high' OR allowHighRisk: true OR riskOverride: 'allow' |
Controlled by policyGate — see below |
Exposing user_owned capabilities
By default capman-mcp only exposes public capabilities — those that require no
authentication. Many real-world agent workflows need to act on behalf of a specific
user: retrieving their orders, updating their account settings, or fetching personalised
data. These capabilities have privacy.level === 'user_owned' in the capman manifest.
To expose them, add an auth block to your config:
module.exports = {
manifest: '/path/to/capman.manifest.json',
baseUrl: 'https://api.your-app.com',
transport: 'stdio',
auth: {
isAuthenticated: true,
userId: 'usr-alice-123', // the user this server instance acts as
role: 'user',
},
allowedCapabilities: [
{ id: 'get_my_orders' }, // user_owned — exposed because auth is set
{ id: 'get_product_catalog' }, // public — always exposed
],
}
What auth does
- The privacy filter in
buildToolListallowsuser_ownedcapabilities through alongsidepublicones. - capman receives the
AuthContexton every tool call and enforcesprivacy.levelat execution time — ifisAuthenticatedisfalse, capman rejects the call. - capman injects
auth.userIdinto params markedsource: 'session'before making the API call. For example, a capability defined with auser_idsession param and path/users/{user_id}/orderswill automatically call/users/usr-alice-123/orders. The agent never sees or supplies theuserId— it is excluded from the MCP input schema entirely.
Privacy levels and auth
privacy.level |
No auth |
auth.isAuthenticated: true |
|---|---|---|
public |
✅ Exposed | ✅ Exposed |
user_owned |
❌ Blocked | ✅ Exposed |
admin |
❌ Blocked | ❌ Blocked always |
Limitations
This is a static, server-level identity. Every tool call on this server instance runs as the same user. This is correct for:
- Personal Claude Desktop setups (one person, one server)
- Single-user API automations
It is not suitable for multi-user deployments where different callers need different identities. Per-request identity requires transport-level auth signal support, which will be added in a future release when the MCP protocol standardises per-request auth headers.
Policy gate and risk levels
Every capability is assigned a risk level automatically on registry publish and at tool-list build time. The derivation rules are applied top-down, first match wins.
| Rule | Condition | Risk level |
|---|---|---|
| 1 | privacy.level === 'admin' |
high |
| 2 | Any CapabilityError.code contains a financial keyword |
high |
| 3 | Resolver uses POST, PUT, PATCH, or DELETE |
medium |
| 4 | privacy.level === 'user_owned' |
medium |
| 5 | GET/HEAD/OPTIONS + public privacy |
low |
Financial keywords (matched case-insensitively as substrings of the error code):
payment, charge, billing, financial, refund, invoice, subscription.
policyGate
When policyGate is true (the default), high-risk capabilities are blocked from
MCP exposure unless explicitly opted in.
module.exports = {
policyGate: true, // default — safe for production
allowedCapabilities: [
{ id: 'get_order' }, // low risk — passes automatically
{ id: 'delete_account', allowHighRisk: true }, // high risk — opted in explicitly
],
}
Disable the gate only for fully trusted internal deployments:
policyGate: false
Registry mode risk overrides
In registry mode, each RegistryEntry carries a riskOverride field that takes
precedence over the computed riskLevel:
riskOverride value |
Effect |
|---|---|
'allow' |
Expose despite high risk (operator has reviewed and approved) |
'block' |
Never expose, regardless of risk level (hard block) |
| absent | Default gate behaviour |
{
"fullyQualifiedId": "my-app/create_payment",
"riskLevel": "high",
"riskOverride": "allow",
"approvedForMcp": true
}
Registry
The registry is a persistent JSON file that tracks every published capability with its approval state, risk level, schema hash, and dependency declarations. It is the source of truth in registry mode and the backing store for the catalog service.
CLI commands
# Publish all capabilities from a manifest into the registry
capman-mcp registry publish --manifest capman.manifest.json --owner ci-bot
# Publish without approving for MCP (pending review state)
capman-mcp registry publish --manifest capman.manifest.json --no-approved-for-mcp
# List all registry entries with status, risk, and approval state
capman-mcp registry list
# Show what would change if you published a new manifest version
capman-mcp registry diff --manifest capman.manifest.json
# Deprecate a capability (with optional successor)
capman-mcp registry deprecate my-app/old_endpoint --successor my-app/new_endpoint
# Show all capabilities that depend on a given capability
capman-mcp registry impact my-app/get_order
# All commands accept --registry <path> to target a non-default registry file
registry list output
ID STATUS RISK APPROVED OWNER
my-app/get_order stable low true ci-bot
my-app/create_payment stable high false ci-bot
my-app/old_search deprecated medium true ci-bot
registry diff output
~ [changed] [low] my-app/get_order
+ [new] [medium] my-app/create_refund
- [removed] my-app/legacy_checkout
[unchanged] my-app/list_products
RegistryEntry fields
| Field | Type | Description |
|---|---|---|
fullyQualifiedId |
string |
"{appSlug}/{capabilityId}" |
schemaVersion |
string |
Manifest schema version at publish time |
owner |
string |
Team or CI identity that last published |
status |
LifecycleStatus |
stable, beta, experimental, deprecated |
schemaHash |
string |
SHA-256 of the capability definition |
approvedForMcp |
boolean |
Whether this capability is exposed via MCP |
riskLevel |
'low' | 'medium' | 'high' |
Auto-derived on publish |
riskOverride |
'allow' | 'block' |
Operator override (optional) |
dependsOn |
string[] |
Explicit dependency declarations (optional) |
publishedAt |
string |
ISO 8601 timestamp of last publish |
deprecatedAt |
string |
ISO 8601 timestamp of deprecation (optional) |
successor |
string |
fullyQualifiedId of the replacement (optional) |
Dependency graph
Declaring dependencies
Set dependsOn on a registry entry to declare that one capability relies on another.
Values are fullyQualifiedId strings:
{
"fullyQualifiedId": "my-shop/order_summary",
"dependsOn": ["my-shop/get_order", "my-shop/get_customer"]
}
Cycle detection
Cycle detection runs automatically on every registry publish. If a publish would
introduce a circular dependency chain, it is rejected before the registry file is
written — the operation is atomic.
Error: Circular dependency detected: my-shop/a → my-shop/b → my-shop/c → my-shop/a
Fix: remove one of the dependsOn declarations that forms this cycle.
Impact analysis
Find all capabilities that would be affected if a given capability changes:
capman-mcp registry impact my-shop/get_order
Impact analysis for: my-shop/get_order
2 capabilities would be affected if this changes:
my-shop/order_summary (stable, medium)
my-shop/checkout_flow (stable, low)
This performs a reverse-graph BFS — it finds every capability that directly or transitively depends on the given one, not just its immediate consumers.
Catalog service
The catalog is a read-only HTTP service that makes your capability registry discoverable. Start it alongside your MCP server or as a standalone process:
capman-mcp catalog start --port 4001 --manifest capman.manifest.json
[capman-mcp] Catalog server running at http://localhost:4001
[capman-mcp] Endpoints:
[capman-mcp] GET /health
[capman-mcp] GET /capabilities
[capman-mcp] GET /capabilities/:fqId
[capman-mcp] GET /capabilities/:fqId/badge
[capman-mcp] GET /capabilities/:fqId/impact
The catalog reloads the registry on every request — it always reflects the current state without a restart.
Endpoints
| Endpoint | Response |
|---|---|
GET /health |
{ ok: true, count: N } |
GET /capabilities |
RegistryEntry[] — supports filters |
GET /capabilities/:fqId |
Single RegistryEntry or 404 |
GET /capabilities/:fqId/badge |
SVG compatibility badge |
GET /capabilities/:fqId/impact |
{ fullyQualifiedId, impacted: string[] } |
Query filters for GET /capabilities
| Parameter | Example | Effect |
|---|---|---|
q |
?q=order |
Case-insensitive substring match on fullyQualifiedId and owner |
risk |
?risk=high |
Filter by low, medium, or high |
status |
?status=stable |
Filter by lifecycle status |
approvedForMcp |
?approvedForMcp=false |
Filter by approval state |
Parameters combine: GET /capabilities?risk=high&approvedForMcp=true
Badge colours
Embed a capability's MCP compatibility badge anywhere SVG is supported:
<img src="http://localhost:4001/capabilities/my-app/get_order/badge" />
| Colour | Meaning |
|---|---|
| 🟢 Green | approvedForMcp: true, risk level low or medium |
| 🟡 Amber | approvedForMcp: true, risk level high — review recommended |
| 🔴 Red | approvedForMcp: false or riskOverride: 'block' |
Matching modes
capman-mcp delegates matching to capman's engine. Three modes trade API cost against matching accuracy. The mode is set per-server in config.
| Mode | Behaviour | Best for |
|---|---|---|
cheap |
BM25 keyword only — zero LLM calls | Registry mode (tool name is explicit) |
balanced |
Keyword first; LLM fallback when confidence < 50% | Most production deployments |
accurate |
LLM over top-3 candidates on every call | High-ambiguity capability sets |
In registry mode, resolveById is used instead of engine.ask(), making the matching
mode irrelevant — the tool name is an exact capability ID.
Verdict handling
Each engine.ask() call returns a verdict that capman-mcp surfaces in the MCP response:
| Verdict | Meaning | MCP response |
|---|---|---|
clear |
High-confidence match, large margin over runner-up | Returned as-is |
marginal |
Top two candidates are close in score | Prefixed with [verdict: marginal] |
uncertain |
Confidence below threshold | Prefixed with [verdict: uncertain] |
The client (Claude) sees the verdict annotation and can ask for user confirmation before
acting on a marginal result.
Audit log
When audit.enabled is true, every tool invocation is written as one JSON line:
{
"ts": "2026-06-13T09:00:00.000Z",
"capabilityId": "get_order",
"verdict": "clear",
"resolvedVia": "keyword",
"durationMs": 42,
"dryRun": false,
"params": ["order_id"],
"error": null
}
Param values are never logged — only param names. The log is append-only and safe to tail in production. In demo mode, the log is written in human-readable format instead.
HTTP transport
For integrations that cannot use stdio:
module.exports = {
transport: 'http',
httpPort: 3000,
}
npx capman-mcp start --config capman-mcp.config.js
# [capman-mcp] MCP server listening on http://localhost:3000
Troubleshooting
Claude Desktop shows no tools after restart
- Ensure all paths in
claude_desktop_config.jsonare absolute. - Run the start command manually in a terminal to see errors directly:
npx capman-mcp start --config /absolute/path/to/capman-mcp.config.js - Verify the manifest is valid:
npx capman validate
Error: config.manifest must be a non-empty string path
The manifest field is missing from your config or is not a string.
allowlist entry "X" not found in manifest
The ID in allowedCapabilities does not exist in your manifest.
Run npx capman inspect to list all valid capability IDs.
allowlist entry "X" filtered out (non-public or deprecated)
The capability exists but has privacy.level !== 'public' or is deprecated.
It cannot be exposed as an MCP tool.
Tool calls return Missing required parameters: <name>
capman could not extract the parameter from the query string. In balanced or
accurate mode, capman will attempt LLM extraction automatically. In cheap mode,
the parameter value must appear literally in the query. Add more examples to the
capability definition to improve extraction.
Circular dependency detected: ...
A registry publish was rejected because dependsOn declarations form a cycle.
Remove one of the declarations named in the error path.
enrichWithOutputSchemas does not support YAML specs yet
Convert your OpenAPI spec to JSON before calling enrichWithOutputSchemas:
npx js-yaml your-spec.yaml > your-spec.json
License
MIT
Установка Capman
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/Hobbydefiningdoctory/capman-mcpFAQ
Capman MCP бесплатный?
Да, Capman MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Capman?
Нет, Capman работает без API-ключей и переменных окружения.
Capman — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Capman в Claude Desktop, Claude Code или Cursor?
Открой Capman на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
автор: modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
автор: xuzexin-hzCompare Capman with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории ai
