catapa-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@catapa-mcpList all employees"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
catapa-mcp
An MCP server exposing CATAPA's HR & payroll APIs as tools, built on top of the official catapa (public, OAuth2) and catapa-private (private, session-authenticated) Python SDKs.
What it exposes
Public API tools (
catapa_*) -- one MCP tool per resource operation in thecatapaSDK, generated automatically at startup by walking the SDK's resource tree (catapa.resource_registry). This covers ~190 resources (employees, payroll, time management, analytics, ...) and several hundred operations in total. Tool names follow the SDK's own path, e.g.catapa_core_employees_list,catapa_core_cost_centers_create.Private API tools (
catapa_private_*) -- thecatapa-privateSDK is a thin, session-authenticated HTTP client rather than a per-endpoint client, so it's wrapped 1:1 as seven generic tools:catapa_private_get,catapa_private_post,catapa_private_put,catapa_private_patch,catapa_private_delete,catapa_private_get_all(auto-paginating), andcatapa_private_session_status. See the private API docs for available paths.
Each half is independent -- set up credentials for one, both, or neither (an unconfigured half is simply skipped, with a warning logged to stderr).
OAuth login (recommended)
catapa-private has no OAuth of its own -- only a direct username/password login -- but its client also accepts a static bearer token, and CATAPA's public API already has a real, browser-redirect OAuth2 authorization-code flow. Setting CATAPA_MCP_AUTH_MODE=oauth uses that flow to authenticate both clients with a single login: the first time the server starts (or whenever the cached token can't be silently refreshed), it opens your browser to CATAPA's hosted login page, waits for the redirect on a local loopback server, exchanges the resulting code for an access/refresh token pair, and caches it to ~/.catapa-mcp/oauth-token.json for future launches. See src/catapa_mcp/oauth.py.
Related MCP server: @slantis/mcp-teamtailor
Install
pip install -e .
# or: uv syncRequires Python 3.11-3.13.
Configure
Copy .env.example to .env and fill in credentials, or set the environment variables directly wherever the server runs (e.g. in your MCP client's config).
# Recommended: a single interactive OAuth login for both APIs (opens your browser)
CATAPA_MCP_AUTH_MODE=oauth
CATAPA_CLIENT_ID=...
CATAPA_CLIENT_SECRET=...
# Or, per-API credentials:
# Public API: either an access token, or OAuth2 client credentials
CATAPA_TENANT=your-tenant
CATAPA_ACCESS_TOKEN=...
# or
CATAPA_CLIENT_ID=...
CATAPA_CLIENT_SECRET=...
# Private API: either an access token, or username/password (session auth)
CATAPA_PRIVATE_ACCESS_TOKEN=...
# or
CATAPA_PRIVATE_USERNAME=...
CATAPA_PRIVATE_PASSWORD=...See .env.example for the full list, including CATAPA_MCP_INCLUDE / CATAPA_MCP_EXCLUDE for scoping the public API's tool count down to specific resource namespaces (e.g. CATAPA_MCP_INCLUDE=core.employees,timemanagement), and CATAPA_MCP_ENABLE_PUBLIC / CATAPA_MCP_ENABLE_PRIVATE for turning either half off entirely.
Run
catapa-mcp
# or
python -m catapa_mcpThe server speaks MCP over stdio.
Claude Desktop / Claude Code
Add to your MCP client's config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"catapa": {
"command": "catapa-mcp",
"env": {
"CATAPA_TENANT": "your-tenant",
"CATAPA_ACCESS_TOKEN": "...",
"CATAPA_PRIVATE_ACCESS_TOKEN": "..."
}
}
}
}Remote deployment (Vercel, private API only, multi-tenant)
src/catapa_mcp/remote/ is a separate, Streamable-HTTP MCP server for deploying to Vercel so multiple people/orgs can connect without each running the server locally. It intentionally only exposes the catapa_private_* tools -- it does not port the public API's ~300 generated tools.
Unlike the stdio server (one shared login, one local token cache), each connecting user authenticates with their own CATAPA account:
The MCP client (Claude) starts an OAuth flow against this deployment.
This deployment redirects the user's browser to CATAPA's real, hosted login page (there's no separate "private API OAuth" -- CATAPA only has OAuth on the public API side, so that's what's used; see
src/catapa_mcp/remote/oauth_provider.py).Once CATAPA redirects back, the resulting CATAPA access/refresh token is sealed (encrypted, via
src/catapa_mcp/remote/crypto.py) directly into the MCP token handed back to the client -- there is no per-user token table.Every subsequent tool call decrypts that request's own token to build a
CatapaPrivateclient scoped to that specific user (src/catapa_mcp/remote/private_tools.py), so different users' requests never share credentials.
The only persistent storage needed is for OAuth client registrations and the few-seconds-lived login handshake (src/catapa_mcp/remote/store.py, backed by Upstash Redis via the Vercel Marketplace integration). Storage is behind the TokenStore abstract interface specifically so a future move to Postgres/MariaDB/etc. is a new subclass wired into build_token_store(), not a rewrite.
Deploying
Attach an Upstash Redis store to the Vercel project (Marketplace tab) -- this sets
UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKENautomatically.Set these environment variables in the Vercel project:
MCP_SERVER_URL=https://your-app.vercel.app # this deployment's own public URL CATAPA_CLIENT_ID=... CATAPA_CLIENT_SECRET=... MCP_TOKEN_ENCRYPTION_KEY=... # generate: python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"MCP_TOKEN_ENCRYPTION_KEYdecrypts every connected user's CATAPA credentials -- treat it as a master secret, and don't rotate it casually (rotating logs everyone out).CATAPA_BASE_URL,CATAPA_AUTHORIZATION_URL, andCATAPA_PRIVATE_BASE_URLare optional overrides with the same defaults as the stdio server.Deploy.
api/index.pyexposes the ASGI app Vercel's Python runtime auto-detects;vercel.jsonroutes all paths to it.Add the deployment as a remote MCP server in your client, pointed at
https://your-app.vercel.app/mcp.
Caveats, since this hasn't been tested against real Vercel/Upstash/CATAPA infrastructure:
CATAPA_AUTHORIZATION_URL's default (https://accounts.catapa.com/oauth2/authorize) is an unverified guess mirroring CATAPA's dev-environment naming; override it if wrong.Vercel's exact zero-config Python build behavior (whether it installs this project's own dependencies from
pyproject.tomlwithout an accompanyingrequirements.txt) hasn't been verified end-to-end here -- if the deploy fails to pick up dependencies, check Vercel's Python runtime docs for the current convention.
How the public API tools are generated
The catapa SDK exposes a fluent resource tree (client.core.employees.list(...)) backed by an auto-generated OpenAPI client, where every operation method is fully typed -- including nested pydantic request/response models. src/catapa_mcp/public_tools.py walks that tree (catapa.resource_registry.ROOT_RESOURCES) at startup, and for every operation:
Copies the SDK method's own signature (minus transport-only kwargs like
_headers) onto a thin async wrapper function.Registers that wrapper as an MCP tool -- the MCP server derives the tool's JSON schema straight from the wrapper's type hints, so nested pydantic models become nested JSON schema automatically.
On invocation, validates/coerces the tool call's arguments back into the SDK's own types, calls the real SDK method, and serializes the (often pydantic) response back to JSON.
This means the tool surface tracks the SDK automatically -- upgrading catapa picks up new/changed endpoints without any code changes here.
Development
uv sync --group dev # or: pip install -e . pytest pytest-asyncio ruff
pytest
ruff check .
ruff format .Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceA template MCP server built with mcp-framework that provides a foundation for building custom tools. Currently includes example tool implementations that can be extended for HR management system integrations.
- Flicense-qualityDmaintenanceFull-coverage, read-only MCP server for the Teamtailor recruitment API. Exposes 18 tools covering candidates, jobs, applications, offers, stages, departments, locations, users, and activities with strict input validation.
- Flicense-qualityCmaintenanceThis MCP server implements a secure OAuth 2.1 authorization server with Google login, enabling authenticated tool execution and a user interface for MCP applications.
- AlicenseAqualityAmaintenanceMCP server for the bexio API, enabling interaction with contacts, sales, accounting, projects, and more through 35 tools. Supports both PAT and OAuth authentication with read-only mode and tool group filtering.35231MIT
Related MCP Connectors
MCP server for the Inistate platform: module discovery, entry management, and activity submission.
MCP server for French (BOAMP) + EU (TED) public procurement data via TenderAPI.
Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/felixadhinata/catapa-mcp-trial'
If you have feedback or need assistance with the MCP directory API, please join our Discord server