About Apideck MCP Server
Apideck MCP Server exposes Apideck Unified API operations to agents through one MCP endpoint, spanning accounting, CRM, HRIS, storage and other domains. Its discovery modes let agents load tools progressively or use a compact code-oriented interface.
Key features
- 01Access 330 tools across 10 APIs
- 02Progressive tool discovery
- 03Static and code-oriented modes
- 04Filter tools by HTTP method scope
- 05Hosted HTTP and local stdio options
Use cases
- 01Manage accounting records and reports
- 02Search and update CRM contacts
- 03Work with files and HR data
- 04Limit agents to read or write operations
MCP support
It exposes Apideck Unified API operations as MCP tools, including accounting, CRM, HRIS, file storage and other domains. Clients can connect to the hosted HTTP endpoint or run the server locally over stdio.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://mcp.apideck.dev/mcpclaude mcp add --transport http apideck-libraries https://mcp.apideck.dev/mcp{"mcpServers":{"apideck-libraries":{"type":"http","url":"https://mcp.apideck.dev/mcp"}}}Open in Cursor{"servers":{"apideck-libraries":{"type":"http","url":"https://mcp.apideck.dev/mcp"}}}Open in VS Code{"mcpServers":{"apideck-libraries":{"type":"http","url":"https://mcp.apideck.dev/mcp"}}}{"mcpServers":{"apideck-libraries":{"serverUrl":"https://mcp.apideck.dev/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
https://mcp.apideck.dev/mcpAuth requiredTools
4| Parameter | Type | Required | Description |
|---|---|---|---|
| scope | enum | No | Filter by mutation scope: "read" (no writes), "write" (creates/updates), or "destructive" (deletes/overwrites). Omit to include all scopes.read | write | destructive |
| domain | string | No | Restrict results to a single tool domain (e.g. "accounting", "hris"). Omit to get the cross-domain index. Use a key returned by a prior no-arg call. |
| search_terms | array | No | Case-insensitive substring terms ANDed across a tool name/description (e.g. ["invoice","create"]). Omit to list everything in the domain. |
Details
From the project READMEApideck MCP Server
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent to 200+ connectors — accounting systems, HRIS platforms, CRM, file storage, and more — through one integration.
Quick Connect
Claude Desktop (.mcpb bundle)
Recommended — prebuilt bundle:
Drag and drop the prebuilt mcp-server.mcpb onto Claude Desktop. Claude reads manifest.json to prompt for credentials and spawn the server — no manual config needed.
Note
Learn more about Desktop Extensions.
Local stdio (npx) alternative:
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"apideck": {
"command": "npx",
"args": ["-y", "@apideck/mcp", "start"],
"env": {
"APIDECK_API_KEY": "YOUR_API_KEY",
"APIDECK_CONSUMER_ID": "YOUR_CONSUMER_ID",
"APIDECK_APP_ID": "YOUR_APP_ID"
}
}
}
}
Restart Claude Desktop after saving. Pin a specific version by replacing @apideck/mcp with @apideck/[email protected].
Claude Code CLI
Set credentials in your shell:
export APIDECK_API_KEY="..."
export APIDECK_CONSUMER_ID="..."
export APIDECK_APP_ID="..."
Hosted (recommended):
claude mcp add --transport http apideck https://mcp.apideck.dev/mcp \
--header "Authorization: Bearer $APIDECK_API_KEY" \
--header "x-apideck-consumer-id: $APIDECK_CONSUMER_ID" \
--header "x-apideck-app-id: $APIDECK_APP_ID"
Local stdio (npx):
claude mcp add apideck \
-e APIDECK_API_KEY="$APIDECK_API_KEY" \
-e APIDECK_CONSUMER_ID="$APIDECK_CONSUMER_ID" \
-e APIDECK_APP_ID="$APIDECK_APP_ID" \
-- npx -y @apideck/mcp start
The start command reads credentials from environment variables only — it does not accept --api-key / --consumer-id / --app-id flags.
Windsurf
Settings → Cascade → Manage MCPs → View raw config, then paste:
{
"mcpServers": {
"apideck": {
"url": "https://mcp.apideck.dev/mcp",
"headers": {
"x-apideck-api-key": "YOUR_API_KEY",
"x-apideck-consumer-id": "YOUR_CONSUMER_ID",
"x-apideck-app-id": "YOUR_APP_ID"
}
}
}
}
Any MCP client (manual JSON)
{
"mcpServers": {
"apideck": {
"url": "https://mcp.apideck.dev/mcp",
"headers": {
"x-apideck-api-key": "YOUR_API_KEY",
"x-apideck-consumer-id": "YOUR_CONSUMER_ID",
"x-apideck-app-id": "YOUR_APP_ID"
}
}
}
}
Claude Desktop (.mcpb plugin bundle)
Apideck ships a Claude plugin bundle (.mcpb — Anthropic's Model Context Protocol Bundle format). Drop it into Claude Desktop and you get the full server (330 endpoint tools + 4 workflow tools) with API key / consumer ID / app ID prompted via the standard plugin UI.
pnpm mcpb:build # → dist/mcp-server.mcpb (~590 KB)
The bundle is built locally; CI publication to GitHub Releases is deferred. Open the .mcpb with Claude Desktop's plugin installer; Claude Desktop reads manifest.json to wire credentials and spawn the server.
Tools
330 tools across 10 unified APIs:
| API | Tools | Coverage |
|---|---|---|
| Accounting | 143 | Invoices, bills, payments, suppliers, customers, journal entries, ledger accounts, purchase orders, tax rates, P&L, balance sheet, and more |
| CRM | 50 | Companies, contacts, leads, opportunities, pipelines, notes, activities, users |
| File Storage | 32 | Files, folders, drives, shared links, upload sessions |
| HRIS | 25 | Employees, companies, departments, payrolls, time-off requests |
| Vault | 23 | Connections, consumers, sessions, custom mappings, logs |
| ATS | 15 | Applicants, applications, jobs |
| Issue Tracking | 15 | Collections, tickets, users, tags, comments |
| Connector | 8 | APIs, connectors, resources, coverage metadata |
| Ecommerce | 7 | Customers, orders, products, stores |
| Webhook | 6 | Webhook subscriptions, logs |
| Proxy | 6 | GET, POST, PUT, PATCH, DELETE, OPTIONS |
Workflow tools
Intent-grouped workflows orchestrate multiple calls behind a single MCP tool — saving agents the round-trips and field-plumbing they routinely get wrong.
| Tool | What it does | Calls |
|---|---|---|
apideck-month-end-close-check | Fans out aged-creditors, aged-debtors, balance-sheet, and P&L in parallel. Returns a partial result when some reports aren't supported by the connector. | 4 |
Hosted
The server is live at:
https://mcp.apideck.dev/mcp
Pass credentials via headers:
| Header | Description |
|---|---|
x-apideck-api-key | Your Apideck API key |
x-apideck-consumer-id | The end-user / customer ID in your app (optional — see below) |
x-apideck-app-id | Your Apideck application ID |
x-apideck-auth-type | Optional. Set to JWT to authenticate with a Vault session token instead of an API key |
Vault session tokens (JWT)
To let an end user's browser or agent call tools without your API key, create a
Vault session
on your backend and pass its session_token instead:
Authorization: Bearer <session_token>
x-apideck-auth-type: JWT
x-apideck-app-id: <your app ID>
x-apideck-consumer-id: <the session's consumer ID>
The server forwards x-apideck-auth-type: JWT on every Apideck API call, the
same way the API Explorer authenticates sessions. Any other value keeps API-key
auth. A few limits:
- The header only takes effect alongside a bearer token in the request. The
server's own
APIDECK_API_KEYis never sent as a JWT. - A session token can't create a new Vault session. If a connection needs re-authorizing, the tool returns the plain error message instead of a re-auth link.
- JWT auth works over HTTP only. The stdio CLI always uses an API key.
Consumer scoping (optional)
The consumer ID is optional at connect time. Leave APIDECK_CONSUMER_ID /
x-apideck-consumer-id unset to start the server unscoped, then supply or
override the consumer per call by passing a consumer_id argument to any tool:
execute_tool({ name: "crm-contacts-all", input: { consumer_id: "acme-inc" } })
Precedence: the per-call consumer_id argument wins over the
APIDECK_CONSUMER_ID env var / x-apideck-consumer-id header.
- Unscoped calls work for application-scoped endpoints that don't need a
consumer — e.g. webhook logs (
webhook-event-logs-all) andvault-connections-all. - Consumer-scoped endpoints called without a consumer return Apideck's
"consumer required" error, so set
consumer_id(or the env/header) for those.
Locking identity (opt-in)
To pin identity to the boot header/env and stop agents from switching consumer
or connection per call, start with --lock-identity (CLI) or append
?lock_identity=true (hosted). Locked calls ignore per-call consumer_id /
service_id arguments. Off by default. Vault consumer tools that take
consumer_id as a path parameter (e.g. vault-consumers-one) only accept the
locked consumer; any other value, or no locked consumer, is refused.
service_id path parameters (e.g. vault-connections-one) are unaffected.
Three Modes
| Mode | Tools exposed | Initial tokens | Best for |
|---|---|---|---|
dynamic (default) | 4 meta-tools | ~1,300 | General-purpose agents, token-sensitive contexts |
static | All 330 tools | ~35–55K | Focused agents doing a specific API |
code | apideck_search + apideck_run | ~600 | Agents that call endpoints programmatically via JS |
Dynamic mode
Agents discover tools progressively — ~85% fewer tokens than loading all 330 schemas upfront:
list_tools({})
→ { total: 330, domains: [{ name: "accounting", count: 143 }, ...],
hint: "Call list_tools(domain=X) or list_tools(search_terms=[...])" }
list_tools({"search_terms": ["invoices"]})
→ accounting-invoices-all, accounting-invoices-add, accounting-invoices-one, ...
describe_tool_input({"name": "accounting-invoices-all"})
→ Full JSON Schema with all parameters
execute_tool({"name": "accounting-invoices-all", "input": {"limit": 10}})
→ Invoice data from the connected accounting system
Put operation fields directly in input, using the contract returned by
describe_tool_input. Dynamic execution validates the arguments before dispatch;
malformed wrappers and schema violations return isError: true with
code: "invalid_tool_input", a field path or issue paths, and no downstream call.
Write tools also reject unknown top-level fields, so nothing undeclared reaches
the API. Validation errors do not echo submitted values. Per-call consumer_id and
service_id overrides remain supported; identity-lock rules still apply.
Request schemas omit read-only response fields, while retaining writable linked
IDs and required path IDs. This does not add idempotency or make write retries safe.
You can combine dynamic mode with a scope filter:
{
"mcpServers": {
"apideck": {
"command": "node",
"args": ["dist/bin/mcp.js", "--mode", "dynamic", "--scope", "read"],
"env": { "APIDECK_API_KEY": "...", "APIDECK_CONSUMER_ID": "...", "APIDECK_APP_ID": "..." }
}
}
}
Code mode
Code mode exposes two tools instead of 330+. Designed for agents that prefer calling endpoints as methods rather than tool calls:
apideck_search— find endpoints by substring, returns camelCase method namesapideck_run— execute a JS script withapideck.<methodName>bound to live endpoint dispatchers, sandboxed innode:vm
apideck_search("invoices")
→ {
count: 4,
endpoints: [
{ name: "accounting-invoices-list", method: "accountingInvoicesList" },
{ name: "accounting-invoices-create", method: "accountingInvoicesCreate" },
{ name: "accounting-invoices-get", method: "accountingInvoicesGet" },
{ name: "accounting-invoices-delete", method: "accountingInvoicesDelete" }
]
}
apideck_run({
script: "return await apideck.accountingInvoicesList({ request: { limit: 5 } })"
})
→ Invoice data from the connected accounting system
The sandbox strips process, require, fs, child_process, and other Node globals — scripts only have access to the apideck object.
Scopes
Filter tools by HTTP method class:
| Scope | HTTP methods | Flag |
|---|---|---|
read | GET, HEAD | --scope read |
write | POST, PUT, PATCH | --scope write |
destructive | DELETE | --scope destructive |
Repeat the flag to combine scopes (--scope read --scope write). On the hosted
endpoint use a comma-separated query param: ?scopes=read,write. Invalid or
empty values are rejected (CLI parse error / HTTP 400). Scopes apply in every
mode, including code.
Connect from Any Agent Framework
Remote (hosted — no local install)
# OpenAI Agents SDK
from agents import Agent
from agents.mcp import MCPServerHTTP
agent = Agent(
name="Apideck Agent",
mcp_servers=[MCPServerHTTP(
url="https://mcp.apideck.dev/mcp",
headers={
"x-apideck-api-key": "...",
"x-apideck-consumer-id": "...",
"x-apideck-app-id": "..."
}
)]
)
# Pydantic AI
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerHTTP
agent = Agent("anthropic:claude-sonnet-4-5", mcp_servers=[
MCPServerHTTP(
url="https://mcp.apideck.dev/mcp",
headers={
"x-apideck-api-key": "...",
"x-apideck-consumer-id": "...",
"x-apideck-app-id": "..."
}
)
])
# LangChain / LangGraph
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"apideck": {
"url": "https://mcp.apideck.dev/mcp",
"transport": "streamable_http",
"headers": {
"x-apideck-api-key": "...",
"x-apideck-consumer-id": "...",
"x-apideck-app-id": "..."
}
}
})
tools = await client.get_tools()
Local stdio (for development)
pnpm install
pnpm build
# Dynamic mode (default)
APIDECK_API_KEY=... APIDECK_CONSUMER_ID=... APIDECK_APP_ID=... node dist/bin/mcp.js start
# Static mode (all 330 tools)
APIDECK_API_KEY=... node dist/bin/mcp.js start --mode static
# Code mode
APIDECK_API_KEY=... node dist/bin/mcp.js start --mode code
# Read-only
APIDECK_API_KEY=... node dist/bin/mcp.js start --scope read
# OpenAI Agents SDK (local stdio)
from agents import Agent
from agents.mcp import MCPServerStdio
mcp = MCPServerStdio(name="apideck", params={
"command": "node",
"args": ["dist/bin/mcp.js", "start", "--mode", "dynamic"],
"env": {
"APIDECK_API_KEY": "...",
"APIDECK_CONSUMER_ID": "...",
"APIDECK_APP_ID": "..."
}
})
agent = Agent(name="Apideck Agent", mcp_servers=[mcp])
Reliability
The runtime automatically retries failed requests so transient errors don't surface to your agent:
- Retried status codes: 408, 500, 502, 503, 504
- Retried network errors:
ECONNRESET,ECONNREFUSED,ETIMEDOUT, and similar - Strategy: exponential backoff, up to 4 attempts, capped at 30 s
- Idempotency: retries only fire on GET, HEAD, PUT, DELETE, OPTIONS, TRACE — POST/PATCH are not retried automatically
Binary Content
File Storage endpoints that return images or audio send them as native MCP content blocks rather than base64 strings in JSON:
{ "type": "image", "data": "<base64>", "mimeType": "image/png" }
{ "type": "audio", "data": "<base64>", "mimeType": "audio/mpeg" }
Agents that support multi-modal MCP content (Claude, GPT-4o) receive the raw bytes — no extra decoding step needed.
License
MIT
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.