AFAS MCP Server
Click on "Deploy 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., "@AFAS MCP ServerShow me the ten most recently changed 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.
AFAS MCP Server
An open-source Model Context Protocol server for AFAS Profit. It lets AI assistants such as Claude Desktop, Claude Code, Cursor or any other MCP client read data through your GetConnectors, inspect connector schemas, and, only when you switch it on, write through UpdateConnectors.
Read-only by default. Insert, update and delete tools exist only when
AFAS_ALLOW_WRITES=true.Your connectors, your rules. The server sees exactly the GetConnectors and UpdateConnectors that the AFAS app connector behind the token allows. Nothing is bundled or hard-coded.
Schema-aware. Field definitions come from AFAS metainfo, and write payloads are validated against the UpdateConnector schema before anything is sent.
Readable filters. Filters are expressed by field id and operator name (
contains,greater_than, ...) and rendered into the AFAS query syntax, including OR groups and the JSON filter fallback.Runs anywhere an MCP client does. stdio for desktop clients, streamable HTTP for shared deployments.
How it fits together
flowchart LR
client["<b>MCP client</b><br/>Claude Desktop · Claude Code · Cursor · ..."]
subgraph server["afas-mcp-server · one AFAS token · read-only by default"]
direction TB
read["<b>Read tools</b> (always on)<br/>afas_connection_info · afas_list_connectors<br/>afas_describe_get_connector · afas_describe_update_connector<br/>afas_get_rows · afas_validate_payload"]
filters["Filters by field id and operator name,<br/>rendered to the AFAS query syntax"]
write["<b>Write tools</b> (only with AFAS_ALLOW_WRITES=true)<br/>afas_insert · afas_update · afas_delete"]
validate["Offline validation against<br/>the UpdateConnector schema"]
read --> filters
write --> validate
end
subgraph afas["AFAS Profit REST services"]
direction TB
meta["metainfo"]
get["GetConnectors"]
upd["UpdateConnectors"]
end
client <-- "MCP over stdio<br/>or streamable HTTP" --> server
read -- "GET" --> meta
filters -- "GET · skip, take, orderby" --> get
validate -- "POST · PUT · DELETE" --> upd
classDef writes fill:#fff4e5,stroke:#e08a00,color:#5c3d00
class write,validate writesThe assistant discovers connectors and fields through AFAS metainfo, reads rows through GetConnectors with filters and paging, and can only reach UpdateConnectors when the operator has enabled writes, and then only after the payload has been checked against the connector's schema.
Related MCP server: Salesforce MCP Server
Quick start
In AFAS Profit, create an app connector (Algemeen > Beheer > App connector), add the GetConnectors and UpdateConnectors the assistant may use, and create a token for a user. Note the environment number from your AFAS Online URL, e.g.
12345inhttps://12345.afasonline.com.Install uv and verify the connection:
export AFAS_MEMBER_ID=12345 export AFAS_TOKEN='<token><version>1</version><data>YOUR_TOKEN_DATA</data></token>' uvx afas-mcp-server --checkYou should see the base URL the server will talk to and the Profit version AFAS reports.
Register the server with your MCP client. For Claude Desktop, add this to
claude_desktop_config.json:{ "mcpServers": { "afas": { "command": "uvx", "args": ["afas-mcp-server"], "env": { "AFAS_MEMBER_ID": "12345", "AFAS_TOKEN": "<token><version>1</version><data>YOUR_TOKEN_DATA</data></token>" } } } }For Claude Code:
claude mcp add afas -e AFAS_MEMBER_ID=12345 -e AFAS_TOKEN='<token>...</token>' -- uvx afas-mcp-serverAsk your assistant something like "Which AFAS connectors can you use?" or "Show the ten most recently changed employees." It will discover connectors, read their field definitions and page through rows.
Until the package is published on PyPI, run it from a checkout instead: uv run afas-mcp-server, or from git with
uvx --from git+https://github.com/schubergphilis/afas_mcp_server afas-mcp-server.
Tools
Tool | Changes data | Purpose |
| no | Which environment the server talks to; proves the token works. |
| no | GetConnectors and UpdateConnectors available to the token, with keyword search. |
| no | Field ids, labels, types and lengths of a GetConnector. |
| no | Fields, mandatory flags, allowed values and nested objects of an UpdateConnector. |
| no | One page of rows with filters, sort order and paging metadata. |
| no | Check an UpdateConnector payload against its schema and show the body that would be sent. |
| yes | Create records (HTTP POST). Only with |
| yes | Change records (HTTP PUT). Only with |
| yes | Delete one record (HTTP DELETE). Only with |
The full parameter reference is in docs/reference/tools.md.
Configuration
Settings come from AFAS_* environment variables or a .env file in the working directory
(see .env.example).
Variable | Default | Effect |
| required | App connector token: the |
| AFAS Online environment number. Required unless | |
|
|
|
| Full REST base URL; overrides member id and environment. | |
|
| Register the insert, update and delete tools. |
|
| Rows per page when a call gives no |
|
| Largest |
|
| HTTP timeout per AFAS call. |
|
| Language of AFAS messages: |
|
| Log level; logs go to stderr so stdio stays clean. |
Command line: afas-mcp-server [--transport stdio|streamable-http] [--host H] [--port P] [--path /mcp] [--check].
Writing to AFAS
Writes are off until you set AFAS_ALLOW_WRITES=true. With writes on, the assistant is instructed to describe the
UpdateConnector, validate the payload and show the change before sending it, and every write tool validates the
payload against the schema first (switch off per call with validate: false). Recommended practice:
Start against your AFAS test environment (
AFAS_ENVIRONMENT=test).Give the token an app connector with only the connectors the assistant needs.
Keep separate tokens, and separate server instances, for read-only and writing use.
Security notes
The token is a credential for your ERP and HR data. Keep it in environment variables or a
.envfile that is not committed; never paste it into a prompt.The server forwards calls to AFAS and nothing else. It stores no data and calls no other service.
The streamable HTTP transport has no authentication of its own. Bind it to localhost or put it behind a reverse proxy that authenticates clients.
How this repository is maintained
An AI agent, running as the Claude Code GitHub Action, maintains
this repository under human supervision. Its standing instructions are in AGENTS.md: what it must never
do (make writing possible by default, touch credentials, add a non-permissive dependency, push to main, publish),
how it runs the checks, and the weekly checklist it works through.
Dependencies. Dependabot proposes updates every Monday after a seven-day release cooldown. A workflow merges GitHub Actions and non-major tooling updates once CI is green; the agent reviews runtime dependencies and major bumps, fixes the code when an update breaks it, and approves or asks a human.
Health. Every week the agent checks failing builds, security audit findings, expiring audit overrides, untriaged issues and a stale lockfile, opens pull requests for what it can fix, and posts a summary on the Maintenance log issue.
Requests. Maintainers ask for changes with
@claudein any issue or pull request. Text from people without write access is treated as data, never as instructions.Humans decide releases, publishing, anything verified against a real AFAS environment, license questions and security disclosures.
Contributors follow the same rules; see CONTRIBUTING.md. The wiring and the repository settings it relies on are described in Maintain the repository with an agent.
Documentation
Full documentation lives in docs/: build and open it with ./workflow.cmd document, or read it
online at https://schubergphilis.github.io/afas_mcp_server/ once GitHub Pages is enabled for the repository.
Developing
Development flow as Paleofuturistic Python
Prerequisite: uv. Every development action runs through ./workflow.cmd <task>: the
first run bootstraps the environment automatically. ./workflow.cmd lint and ./workflow.cmd test are the two you
will use most.
The scaffold manual lives in the docs' Developer section: start with First-run setup; the full command list is in the Invoke task catalog.
License
Apache-2.0. AFAS and AFAS Profit are trademarks of AFAS Software B.V.; this project is not affiliated with AFAS.
This server cannot be deployed
Maintenance
Related MCP Connectors
- DigiDataOAuthnl.digi-data
Read-only business data from Exact Online, Twinfield, AFAS and 30+ sources for your AI.
1 AFAS AI Connect: hosted MCP server for AFAS Profit.
Connect Exact Online to your AI assistant via MCP. Manage Exact Online with natural language.
weclapp ERP in your AI assistant: reads instantly, writes only after a preview you approve.
Related MCP Servers
- FlicenseCqualityNot gradedmaintenanceEnables AI assistants to securely access and interact with Simplicate business data including CRM, projects, timesheets, and invoices through natural language. Supports searching across resources and retrieving detailed information about organizations, contacts, and project data.590-
- FlicenseAqualityDmaintenanceEnables AI assistants to interact with Salesforce data by listing objects, describing fields, and executing SOQL queries.4-
- FlicenseAqualityCmaintenanceEnables AI assistants to interact with SMB platform APIs for querying business data, managing tasks, accessing connectors, dashboards, and monitoring security.16-
- AlicenseAqualityBmaintenanceLets AI assistants safely explore a Matrix42 instance by discovering web services and the data model, running validated ASQL queries, searching the service desk, and previewing ticket actions — read-only by default and without exposing credentials.531 npmMIT