@graniteco/mcp
v0.1.0
Published
Local STDIO MCP server for the Granite Agent API — search, list, read, and ask your Granite document vault from Claude Desktop/Code, Cursor, or any MCP client.
Readme
Granite MCP server
A local Model Context Protocol server that lets an agent — Claude Desktop, Claude Code, Cursor, Codex, or any MCP client — search, list, read, and ask your Granite document vault.
It's a thin STDIO wrapper over the read-only Granite Agent API. All auth, per-user scoping, prompt-injection sanitization, audit logging, and rate limiting happen server-side in the API — this shim just exposes the endpoints as MCP tools and turns API errors into clear, agent-actionable messages.
Read-only. No uploads or writes — those stay on the web app + email-in.
Tools
| tool | what it does | required scope |
|---|---|---|
| search_vault | ranked search (hybrid / keyword / semantic) → metadata + snippet | documents:read |
| list_documents | browse the vault, cursor-paginated | documents:read |
| get_document | full structured fields by id; include_full_text adds the OCR body | documents:read |
| ask_vault | natural-language Q&A across the vault → synthesized answer + citations | vault:ask |
Setup
- Granite plan: the API is paid-only. Free/canceled accounts get a clear
feature_lockederror. - Mint a token: in Granite, go to Settings → Developer → Access tokens, create
a token with the scopes you want (
documents:read, optionallyvault:ask), and copy thegra_live_…value — it's shown once. Treat it like a password: it can read everything in your vault, including sensitive documents. - Configure your client (below). The server reads two env vars:
GRANITE_API_KEY— required, yourgra_live_…token.GRANITE_API_BASE— optional, defaults tohttps://api.granite.co/v1.
Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"granite": {
"command": "npx",
"args": ["-y", "@graniteco/mcp"],
"env": { "GRANITE_API_KEY": "gra_live_your_token_here" }
}
}
}Claude Code
claude mcp add granite --env GRANITE_API_KEY=gra_live_your_token_here -- npx -y @graniteco/mcp…or add it to .mcp.json:
{
"mcpServers": {
"granite": {
"command": "npx",
"args": ["-y", "@graniteco/mcp"],
"env": { "GRANITE_API_KEY": "gra_live_your_token_here" }
}
}
}Cursor
Add to ~/.cursor/mcp.json (or a project .cursor/mcp.json):
{
"mcpServers": {
"granite": {
"command": "npx",
"args": ["-y", "@graniteco/mcp"],
"env": { "GRANITE_API_KEY": "gra_live_your_token_here" }
}
}
}Run from source (until the npm package is published)
cd mcp
npm install
npm run build # → dist/index.jsThen point your client's command/args at the built file instead of npx:
{
"mcpServers": {
"granite": {
"command": "node",
"args": ["/absolute/path/to/granite/mcp/dist/index.js"],
"env": { "GRANITE_API_KEY": "gra_live_your_token_here" }
}
}
}Develop
npm run build # tsc → dist/
npm test # builds, then runs node --test (mocked fetch — no network)
npm start # run the built server on stdioTests stub fetch and assert each tool hits the right endpoint, sends the bearer
token, and maps every API error code to a clean tool error. No live vault needed.
