@capsulesecurity/capsule-mcp-server
v1.0.14
Published
Query your Capsule tenant from any MCP-compatible AI client
Keywords
Readme
@capsulesecurity/capsule-mcp-server
An MCP server that lets any MCP-compatible AI client query a Capsule tenant.
It runs locally over stdio and authenticates as a Capsule service account using the
OAuth 2.0 client_credentials grant. Access is read-only and scoped to the single tenant
that owns the service account.
Setup
Create a service account in Capsule under Settings > Service Accounts. The client secret is shown only once, at creation time.
{
"mcpServers": {
"capsule": {
"command": "npx",
"args": ["-y", "@capsulesecurity/capsule-mcp-server"],
"env": {
"CAPSULE_CLIENT_ID": "<client id>",
"CAPSULE_CLIENT_SECRET": "<client secret>"
}
}
}
}| Variable | Required | Default |
| ----------------------- | -------- | ------------------------------------------------ |
| CAPSULE_CLIENT_ID | yes | - |
| CAPSULE_CLIENT_SECRET | yes | - |
| CAPSULE_API_URL | no | https://portal.us-east1.capsulesecurity.io/api |
CAPSULE_API_URL selects the regional deployment. It defaults to US (us-east1); EU tenants
must set it to https://portal.eu-west4.capsulesecurity.io/api. It must be https, except on
localhost/127.0.0.1 for local development.
Telemetry
The server reports usage analytics (tool calls with their arguments and responses, latency,
errors) to PostHog to help us improve the integration experience. A random installation ID stored
in ~/.capsule/mcp-installation-id (deleting it resets it) and a SHA-256 hash of the OS machine
identifier are sent to count installs and distinct host OS installations. The host ID changes when
the OS is reinstalled and is shared by cloned VM images. Set CAPSULE_TELEMETRY_DISABLED=1 to opt
out.
Tools
describe_type returns the GraphQL SDL for any type, input, or enum. The schema is fetched
from the Capsule API (GET /v1/graphql/introspection) on the first tool call and cached in
memory for 5 minutes, so it tracks the deployment the server talks to.
query_graphql runs a read-only GraphQL query. Queries are parsed and validated against that
schema before they are sent, which is what makes wrong field names come back as
specific, correctable errors - Capsule replaces GraphQL error detail with a generic message in
production. Non-query operations are rejected, and large results are trimmed with a
__truncated marker carrying the original count.
generate_report renders an ordered list of content blocks (summary, threats, section,
chart) into a branded PDF report and returns it as a base64-encoded resource
(application/pdf) alongside a short text confirmation. Chart blocks are Chart.js
configurations, rasterized server-side to a PNG before layout. Rasterizing a chart requires the
optional native dependency @napi-rs/canvas; if it isn't installed, generate_report returns
an error explaining that it needs to be added alongside the package rather than failing
silently or producing a report without its charts.
Prompt and resources
The build_report prompt returns the report-builder skill's instructions - scoping the report,
gathering data with query_graphql, and assembling blocks for generate_report - so a client
can surface it as a guided starting point.
Reference material for report structure and brand tone is exposed as MCP resources:
capsule://skills/report-builder/references/reports/<file>.md- one file per audience (risk-analysis.md,analyst.md,ai-engineer.md,ciso-executive.md).capsule://skills/capsule-brand/SKILL.md- Capsule's brand voice and style guidelines.
Access model
A service account can read everything the VIEWER role permits within its own tenant.
There is no finer-grained control: no per-tool scopes, and no way to grant one connected
client less access than another. Session and activity message bodies are redacted for
VIEWER, so this server can read security metadata but not raw prompt or tool-output text.
Requests are limited to 60 per minute per service account, so give each connected client its own account rather than sharing one.
Everything above is enforced by the Capsule API. The package runs on the user's machine and is therefore untrusted - nothing it does locally is a security control.
Rotating and revoking credentials
A service account holds up to two active secrets, so a new one can be added and the configuration updated before the old one is revoked.
Revoking a secret stops new access tokens from being issued immediately, but a token already issued stays valid until it expires, within 15 minutes. Delete the service account to cut access off without waiting.
Local development
pnpm nx run mcp-server:build
pnpm nx run mcp-server:testPoint a client at the local build with an absolute path instead of npx, and set
CAPSULE_API_URL to http://localhost:4000/api:
{
"mcpServers": {
"capsule": {
"command": "node",
"args": ["<repo>/libs/mcp-server/dist/index.js"],
"env": {
"CAPSULE_CLIENT_ID": "<client id>",
"CAPSULE_CLIENT_SECRET": "<client secret>",
"CAPSULE_API_URL": "http://localhost:4000/api"
}
}
}
}Publishing
Published to npm as @capsulesecurity/capsule-mcp-server.
Releases are cut by hand for now, from a clean checkout of main:
pnpm nx run mcp-server:build
cd libs/mcp-server && pnpm publish --access publicBump the version in package.json and SERVER_VERSION in src/server.ts together.
