b1-mcp-server
Provides guarded access to SAP Business One through both the underlying HANA/MS SQL database and the Service Layer OData API (v1/v2), enabling schema inspection, read-only SQL queries, and Service Layer GET/write requests (PATCH, POST, DELETE) across multiple client environments, with per-profile method restrictions and human approval for writes.
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., "@b1-mcp-server Switch to client_a_prd and list open sales orders"
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.
b1-mcp-server
A secure Model Context Protocol server that gives an AI client (e.g. Claude Code) guarded access to SAP Business One via both the database (HANA / MS SQL) and the Service Layer OData API.
Features
7 MCP tools:
connect_database,execute_sql,execute_service_layer(GET),execute_service_layer_write(PATCH / POST / DELETE),execute_service_layer_write_unattended(the same writes without approval, development profiles only),get_schema_info,check_connection.Multi-environment: switch between client databases at runtime via named connection profiles. No restart needed.
Read-only by design: the SQL path executes only
SELECT. EveryINSERT/UPDATE/DELETE/DROP/CREATE/ALTER/EXECis blocked server-side with no confirmation bypass — writes are handed to a human to run in a real DB client.Server-side guardrails: all raw SQL submitted to
execute_sqlgoes through the same validation whether the user or the AI wrote it. AnonymousDO BEGIN..ENDblocks are classified by the most dangerous statement inside them, so a write hidden behind a trailingSELECTis still a write.Audit trail: selected-profile connection attempts and database/Service Layer calls that reach policy or execution are recorded as JSON Lines, including policy denials.
Rate limiting per tool with sliding window.
Related MCP server: SAP Business One MCP Server Sample
Install
Requires Node.js 22 or newer.
npx b1-mcp-serverOr add to your Claude Code MCP config:
{
"mcpServers": {
"b1-db": {
"command": "npx",
"args": ["-y", "b1-mcp-server"]
}
}
}Dependencies
Five runtime dependencies: @modelcontextprotocol/sdk, zod,
@sap/hana-client and mssql (plus generic-pool, which backs the HANA
connection pool). Database access is a local driver — src/db/directDb.ts —
built directly on the HANA and MS SQL clients; Service Layer traffic goes
through the strict-TLS adapter in src/sl/serviceLayerAdapter.ts using Node's
own fetch and https. No HTTP framework, no axios, no PostgreSQL driver.
The package ships with no overrides block, so npx -y b1-mcp-server installs
the same tree a project install does (overrides never applied to npx, which runs
without a root package.json). As of 1.6.0, npm audit --omit=dev reports 0
vulnerabilities.
Connection profiles
The server starts unconnected. Connections are loaded from
~/.claude/connections.json (one profile per environment) and selected at
runtime by the AI via the connect_database tool.
Profile matching behavior in connect_database:
Exact match by
idordbNameis preferred.Partial matches are accepted only when they resolve to a single profile.
Ambiguous partial matches are rejected with a list of candidates.
Example ~/.claude/connections.json:
[
{
"id": "client_a_prd",
"dbType": "hana",
"dbServer": "10.0.0.10:30015",
"dbName": "SBO_CLIENT_A",
"dbUser": "B1ADMIN",
"dbPassword": "•••",
"slUrl": "https://10.0.0.10:50000/b1s/v2",
"slUser": "manager",
"slPassword": "•••",
"slAllowedMethods": ["GET", "PATCH", "POST"]
},
{
"id": "client_b_hmg",
"dbType": "mssql",
"dbServer": "10.0.0.20:1433",
"dbName": "SBO_CLIENT_B_HMG",
"dbUser": "SA",
"dbPassword": "•••"
}
]Every profile requires id, dbType and dbName. Add dbServer and dbUser
to configure DirectDb; add slUrl and slUser to configure Service Layer.
Each configured side also requires its non-empty password (dbPassword or
slPassword). Missing/empty passwords fail locally without a login attempt,
avoiding an unnecessary failure that may count toward account lockout under the
configured login policy. Non-empty password strings are passed through without
trimming. Either side, or both sides, can be configured in one profile.
slAllowedMethods (optional) lists the HTTP verbs the Service Layer tools may
send for that profile: any of GET, PATCH, POST, DELETE
(case-insensitive). Without it a profile is read-only (["GET"]); every write
verb must be listed explicitly. PUT is not supported, because it
replaces the whole entity and wipes every field the body omits. An invalid
value (unknown verb, empty list, not an array) skips that profile instead of
guessing. The list is applied on connect and printed by connect_database;
editing it re-logs the Service Layer on the next connect_database call.
Allowing a write verb does not waive approval: every write still needs the
per-call human acceptance described under the security posture.
slWriteApproval (optional) chooses who approves a write. "elicitation"
(default): the server asks through an MCP approval form. "client": the server
sends no form and relies on the MCP client's own permission prompt — for
setups where the form cannot reach the user, such as Claude Code Remote
Control, which forwards permission prompts but not MCP forms. client is
honoured only when the MCP client identifies itself as Claude Code; any other
client falls back to elicitation. The server cannot see that prompt, so the
mode is only as strong as the client's permission settings: list
mcp__<server-name>__execute_service_layer_write under permissions.ask,
never allow, and do not use it with --dangerously-skip-permissions. Without
that rule, answering the first prompt with "Yes, don't ask again" saves an
allow rule and every later write runs unprompted. Keep
production profiles on elicitation. connect_database prints the mode that
applies to the current client; editing it re-logs the Service Layer.
"none" is for development companies where a prompt on every write slows the
work down. execute_service_layer_write behaves as in client mode, and the
profile also unlocks execute_service_layer_write_unattended, which runs the
same writes with no approval at all, for any MCP client. That tool refuses
every profile not set to "none", so you can list
mcp__<server-name>__execute_service_layer_write_unattended under
permissions.allow and keep the normal write tool under permissions.ask:
development profiles run unprompted and every other profile still prompts. The
opt-in lives only in the connections file, so it is only as safe as that file:
never set "none" on a profile that points at production data.
Both SAP Service Layer roots are supported: /b1s/v1 for OData v3 and
/b1s/v2 for OData v4. Login, health checks and relative Service Layer requests
use the exact root configured by the profile. Request validation is
version-neutral; callers pass only the relative endpoint (for example,
Items?$select=ItemCode&$top=1). OData query and payload differences remain
the caller's responsibility; configure the root supported by the target SAP B1
installation. SAP deprecated OData v3 starting with SAP Business One 10.0 FP
2405 and made OData v4 the primary protocol, so prefer /b1s/v2 when the target
installation supports it; see the
Service Layer API reference.
Encrypted credentials (optional, recommended)
The profiles can be stored encrypted in ~/.claude/connections.enc.json
instead of the plain-text file (same profile array, AES-256-GCM, key derived
from a passphrase with scrypt). Manage it with the creds subcommand of the
same binary. Every command reads the passphrase and the passwords only from
an interactive terminal: never from an argument, environment variable or
pipe, so they stay out of shell history and out of anything an AI tool call
can type.
b1-mcp creds migrate # encrypt the existing plain-text file (once)
b1-mcp creds init # or start an empty encrypted file
b1-mcp creds add # add a profile
b1-mcp creds edit <id> # Enter keeps a value, "-" clears it
b1-mcp creds remove <id>
b1-mcp creds list # ids and capabilities, never passwords
b1-mcp creds passwd # change the passphrase
b1-mcp creds unlock # unlock every running serverWith npx, the same commands are npx b1-mcp-server creds … (for example
npx b1-mcp-server creds edit client_a_prd). From a clone, run
node /path/to/dist/index.js creds …. The <id> is the first column of
creds list (or of connect_database with "list"). The locked server prints
the exact unlock command for its own install.
With an encrypted file the server starts locked:
connect_databaseanswers with the unlock command and nothing else. Runcreds unlockin your own terminal. It sends the passphrase over a Unix socket in a private directory ($XDG_RUNTIME_DIR/b1-mcp/, or~/.claude/run/; mode0700, socket0600). The server keeps only the derived key in memory, closes the socket, and stops accepting attempts after 5 wrong passphrases until it restarts. Oneunlockreaches every running server (Claude Code, Codex…).The passphrase is never asked for through the MCP client.
add/edit/removetake effect on the nextconnect_databasewithout a new unlock. Afterpasswd, running servers lock again on their next read.migratedoes not delete the plain-text file. Change the database and Service Layer passwords afterwards (old copies may survive in backups and sync folders), then delete it. While both files exist the server refuses the plain-text one.Plain text stays supported, with a warning in the logs and in
connect_databaseoutput.Native Windows: encrypted credentials are not supported yet (no private Unix socket); use the plain-text file there, or run under WSL.
Forgotten passphrase = recreate the profiles; there is no recovery.
What it protects: copies of the file (stolen disk, backups, cloud sync,
malware that copies files, the Windows side reading a WSL disk). What it does
not: code running as your own OS user, which can replace the server or read its
memory; a keylogger. An AI agent with shell access runs as your OS user, so
encryption alone does not keep the credentials from it. With npx this holds
in full: the package is unpacked into your npm cache, which your user (and the
agent) can modify.
Separate OS user (strong boundary, manual setup)
The boundary against same-user code is a dedicated OS user that owns the
credentials. It cannot be set up through npx; on Linux, roughly:
Create a system user (e.g.
b1mcp) with a private home. The connection files, audit log, trust store and unlock socket follow that user's home.Install the package root-owned (e.g.
/opt/b1-mcp,npm ci --omit=devas root) and run it with a root-ownednode, never one under your home (nvm).Allow exactly that command with a
sudoersrule (NOPASSWD, no extra arguments, noSETENV, environment reset), and set the MCP command tosudo -n -u b1mcp <that command>. Runcredsthroughsudo -u b1mcpwith your password, so only a human can add profiles or unlock.
This only holds if your user cannot become root without a password. Check for
passwordless sudo, membership in the docker group, and on WSL the
Windows interop: from inside the distro, wsl.exe -u root gives root with no
password, so a separate Linux user is not a boundary while interop is enabled
([interop] enabled=false in /etc/wsl.conf disables it, and with it every
Windows .exe call from Linux). Where that is not acceptable, rely on the
encryption above and run the server on a host the agent cannot reach.
Security model
The server does not intentionally interpolate profile passwords into MCP tool
responses or audit entries. Passwords are read from
~/.claude/connections.json inside the server process and passed directly to
the configured database or Service Layer endpoint for login. The Service Layer
adapter retains only the session cookie afterward, not the username or
password. Database-driver and Service Layer error messages are returned and
audited verbatim for diagnosis, however, so there is no general-purpose secret
redaction boundary around arbitrary upstream error text. Do not place secrets
in profile IDs, database names, URLs or other non-password metadata. This
protocol-level protection also does not stop an AI host that has unrestricted
same-user shell or filesystem access from opening the file directly; see the
hook guidance below.
Service Layer connections require HTTPS with normal certificate validation by
default. For an internal certificate authority, set NODE_EXTRA_CA_CERTS to
the CA bundle before starting the MCP process.
For a legacy SAP installation whose certificate cannot be renewed, the first
connect_database call inspects TLS without sending credentials and requests
explicit approval through MCP form elicitation. An accepted certificate is
stored by canonical https://host:port origin in
~/.claude/service-layer-trust.json (mode 0600), so profiles sharing one SL
endpoint share one pin. The file is created after explicit approval or after a
matching legacy manual profile pin is migrated successfully, and contains no
credentials. A changed certificate requires approval again; clients without
elicitation support fail closed. Legacy manual profile pin fields remain
accepted only for that one-time migration into this local store.
Once a certificate is pinned, that exact fingerprint is the whole check —
hostname verification is not applied on top of it. SAP B1 issues its self-signed
Service Layer certificate to the machine's short name (DNS:MYSERVER) while
clients normally connect by FQDN, so re-verifying the name would reject an
already-approved certificate with no way to accept it. slTlsServerName is
therefore only the SNI name sent during the handshake, for hosts that serve a
different certificate per name; it is not needed to make a pinned FQDN
connection work. Service Layer URLs may use DNS names, IPv4 or IPv6. For an IP
URL, SNI is omitted unless slTlsServerName supplies a DNS hostname; a legacy
IP-valued slTlsServerName is accepted as a no-op. Older trust-store records may
still carry serverName as a compatibility fallback, but new SNI configuration
belongs in the connection profile rather than in certificate trust metadata.
Profiles reload on every connect_database call. A DB-only profile can gain
slUrl, slUser and slPassword while its DB connection is active; the next
call keeps that DB connection and initializes only Service Layer.
Global certificate verification disablement is never supported: the adapter
refuses to connect when NODE_TLS_REJECT_UNAUTHORIZED=0 is present.
What the AI does see when it calls connect_database with "list":
profile
iddbName,dbTypea capability flag (
DB,SL,DB+SL)an
activemarker when either configured side is currently connected
Recommendations for your connections.json:
Lock the file to your user only.
Linux/macOS:
chmod 600 ~/.claude/connections.json.Windows:
icacls "%USERPROFILE%\.claude\connections.json" /inheritance:r /grant:r "%USERNAME%:F".
Do not commit it to any git repository or share it via cloud sync.
On POSIX systems, the server fails closed and refuses to load a profile file that grants any permission to group or other users.
Each user maintains their own copy. Credentials never come from this npm package.
Claude Code hook and sandbox guidance
Use a centrally managed Claude Code PreToolUse hook or equivalent host policy
to deny AI-issued access to the canonical resolved path of
connections.json. Cover every filesystem-capable tool (Read, Grep,
Glob, edit/write tools and filesystem MCP servers), not only literal filename
matches. Shell commands are the difficult case: matching the path text is not
sufficient because commands, working directories and symlinks can access it
indirectly. Prefer a host filesystem sandbox that denies the credential path;
otherwise require approval for shell access outside the workspace.
The hook/policy must live outside AI-writable project and user settings. For
Claude Code enterprise deployments, install it in the platform's managed
settings so project instructions cannot override it. Deny AI writes to
service-layer-trust.json as well; reading that file is not secret, but its
integrity controls which legacy certificate is trusted.
Hooks are defense in depth, not an OS security boundary. They govern tool calls
issued through the AI host; they cannot stop this MCP process, another local
process, or a malicious npm package running as the same OS user from reading a
mode-0600 file. Strong isolation requires a dedicated OS identity, sandbox,
or remotely hosted credential broker. See the
Claude Code hooks and
server-managed settings
guidance.
Configuration (env vars)
All optional.
There is no .env file. The server reads process.env directly and never
loads a dotenv file, so dropping a .env next to it does nothing. For a stdio
MCP server the client owns the environment — set variables in the env block of
your MCP configuration, which the client passes to the spawned process:
{
"mcpServers": {
"b1-db": {
"command": "npx",
"args": ["-y", "b1-mcp-server"],
"env": {
"MCP_QUERY_TIMEOUT_MS": "120000",
"MCP_SL_WRITES_ENABLED": "false"
}
}
}
}Credentials are not configured this way — they live only in
connections.json, which is resolved from your home directory and therefore
found regardless of where npx runs from.
Variable | Default | Purpose |
|
| Path to profile file |
|
| Audit log JSONL file. Unset or empty uses the default path |
|
| Stderr verbosity: |
|
| Max SQL length in characters |
|
| Max calls per tool per window |
|
| Rate-limit window |
|
| Statement ceiling. A query still running at this point is aborted. Raise it if a legitimate report needs longer |
|
| Service Layer login/request timeout |
|
| Local non-secret certificate trust store |
|
| Maximum relative OData URL length |
|
| Maximum serialised PATCH/POST body length |
|
| Emergency kill switch for every Service Layer write (PATCH, POST, DELETE); |
|
| How long a human gets to answer an approval form (certificate trust, Service Layer write) before it fails closed |
|
| Max rows returned to the model; extra rows are cut and announced |
|
| Max characters of result JSON, applied after the row cap |
|
| The exact value |
The numeric limits above must be positive integers. An unset or whitespace-only
value uses the default. Any other invalid value (including 0, a negative or a
non-integer) reports the fallback on stderr and uses the default — a
misconfigured limit never means "no limit". MCP_LOG_LEVEL likewise uses
info when unset/empty and reports a fallback for any other invalid value.
Guardrail summary
The SQL path is read-only, so the live answer does not depend on which table you touch:
Operation | Any table (SAP core, UDT, custom, temp) |
SELECT | allow, subject to the SELECT-specific restrictions below |
INSERT / UPDATE / DELETE / DROP | block — run it yourself in a DB client |
CREATE / ALTER | block |
EXEC / EXECUTE / CALL | block — stored procedures cannot be run through this server |
Also blocked: multi-statement queries (semicolons outside BEGIN..END),
unterminated quotes or brackets, sequence advancement (NEXTVAL /
NEXT VALUE FOR), OPENQUERY / OPENROWSET / OPENDATASOURCE,
SELECT ... INTO <table>, and high-impact SQL Server lock hints (UPDLOCK,
XLOCK, TABLOCK, TABLOCKX, HOLDLOCK, SERIALIZABLE,
REPEATABLEREAD).
Service Layer requests allow only the verbs in the profile's slAllowedMethods
(default GET only); PUT is never available. PATCH and DELETE require
one directly keyed entity endpoint; POST accepts an entity set, a service
operation or one action on a keyed entity (Orders(12)/Close); writes take no
query options. Writes go through a separate tool, execute_service_layer_write,
so a client can gate them by tool name while GETs stay unprompted. Every write
names its target database, which must match the connected Service Layer.
By default every write requires explicit user acceptance through MCP form
elicitation. The approval screen is bound to the database, Service Layer root,
endpoint, exact body, field list and SHA-256 body hash. A client without
elicitation support cannot write. A profile with slWriteApproval: "client"
replaces the form with Claude Code's permission prompt, and one with
slWriteApproval: "none" also accepts unapproved writes through
execute_service_layer_write_unattended (see the profile fields above).
MCP_DRY_RUN=true never executes a write,
and MCP_SL_WRITES_ENABLED=false disables every write globally.
The per-table classification model (SAP_CORE / SAP_USER / CUSTOM / TEMP with
per-operation rules) still exists in src/guardrails/rules/ and is fully
tested, but on the read-only server it is not reachable from the live path.
See SECURITY.md for the full model and its known limitations.
Agent skill
skills/b1-mcp-server/SKILL.md teaches an AI agent how
to use these tools: connect first, what each refusal means and what to do about it, why a
HANA timeout reports a dropped socket, how truncated results look, and how Service Layer
writes are approved. To install it in Claude Code, copy the folder into
~/.claude/skills/; other agents that read SKILL.md files take it from their own skills
directory.
Development
npm install
npm run build
npm run test
npm run test:watch
# Optional aliases (same behavior, useful if you prefer explicit naming):
npm run test:bash
npm run test:watch:bashFrom a source checkout only, run this quick connection sanity check using a
profile from connections.json (scripts/ is not shipped in the npm tarball):
npx tsx scripts/test-connection.ts <profile-id>License
MIT — see LICENSE.
Available Tools
7 toolscheck_connectionA
Check if the database and Service Layer connections are active and alive. Pings DirectDb (SELECT query) and Service Layer (GET request) independently. No parameters required. Reports status for both connections.
Inputs: no named parameters.
connect_databaseA
Switch the active database and Service Layer connection to a different SAP Business One environment. Searches connection profiles by ID or database name (case-insensitive). Partial matches are only accepted when they resolve to a single profile.
Each profile can include DirectDb (DB) credentials, Service Layer (SL) credentials, or both. When switching environments, each stale or non-matching side is disconnected before replacement; a healthy side that still matches the selected profile remains active. If only one side connects successfully, it remains active - retry the failed side after fixing credentials. Tracks failed login attempts per profile and warns about account lockout risk under the configured login policy.
Available profiles: (no profiles loaded)
Use "list" as the query to reload and list all available profiles.
Inputs: query (required).
execute_service_layerA
Execute a read-only OData GET against the currently connected SAP Business One Service Layer. Writes go through execute_service_layer_write.
Denied when the connected profile's slAllowedMethods (printed by connect_database) omits GET. Query options are allowed; absolute URLs, Login/Logout and $batch are denied.
Inputs: url (required), method.
execute_service_layer_writeA
Execute a guarded OData write (PATCH, POST or DELETE) against the currently connected SAP Business One Service Layer. These are real writes to the company database.
The verb must be in the connected profile's slAllowedMethods, and database must equal the connected Service Layer database exactly — connect_database prints both. A mismatch is denied.
Approval follows the profile's slWriteApproval, also printed by connect_database. "elicitation" (default): the server asks the user through an MCP approval form; clients without form elicitation cannot write. "client" or "none": the server executes after this client's own permission prompt, honoured only for Claude Code. On a "none" profile, prefer execute_service_layer_write_unattended, which does the same write without any approval; use this tool there only when the user asks to confirm the write. MCP_DRY_RUN previews but never executes a write, and MCP_SL_WRITES_ENABLED=false disables every write globally.
PATCH and DELETE accept one directly keyed entity endpoint only. POST accepts an entity set, a service operation, or one action on a keyed entity (Orders(12)/Close). Query options, navigation paths, absolute URLs, Login/Logout and $batch are denied.
Inputs: url (required), method (required), database (required), body.
execute_service_layer_write_unattendedA
Execute a guarded OData write (PATCH, POST or DELETE) with NO approval of any kind, for development companies. Denied unless the connected profile has slWriteApproval "none" (printed by connect_database); otherwise use execute_service_layer_write. These are real writes to the company database.
Every other rule of execute_service_layer_write applies unchanged: database must equal the connected Service Layer database, the verb must be in slAllowedMethods, the same endpoint shapes are enforced, MCP_DRY_RUN previews and MCP_SL_WRITES_ENABLED=false disables it.
Inputs: url (required), method (required), database (required), body.
execute_sqlA
Execute a raw SQL statement against the currently connected database. All SQL, whether written by the user or generated by you, goes through the same server-side validation.
IMPORTANT: Before calling this tool, you MUST confirm which database the user intends to query. If the user has not explicitly stated the target database in their message, ASK them first. Do NOT assume the currently connected database is the intended target.
READ-ONLY: only SELECT (and read-only DO BEGIN...END blocks) execute. Data-changing statements are blocked server-side.
If the user needs a write (INSERT/UPDATE/DELETE), do NOT call this tool — generate the SQL and give it to the user to run in a real DB client (HANA Studio / DBeaver / hdbsql), where a human can review the statement and control its transaction handling.
Rules enforced server-side:
READ-ONLY: INSERT/UPDATE/DELETE/DROP are blocked for everyone — no confirmation bypass.
Direct EXEC/EXECUTE/CALL: blocked (stored procedures are disabled).
CREATE/ALTER: blocked.
MS SQL pass-through (OPENQUERY/OPENROWSET/OPENDATASOURCE): blocked.
Inputs: query (required).
get_schema_infoA
Retrieve metadata about tables, columns, or procedures in the currently connected database. Read-only. Use this to explore the schema before writing queries. For "columns": provide the table name in "filter". For "tables"/"procedures": filter is optional (LIKE pattern).
IMPORTANT: Before calling this tool, you MUST confirm which database the user intends to query. If the user has not explicitly stated the target database in their message, ASK them first. Do NOT assume the currently connected database is the intended target.
Inputs: objectType (required), filter.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Most tools target clearly distinct operations: connection switching, health check, schema introspection, raw SQL, and OData reads/writes. The only real overlap is execute_service_layer_write vs execute_service_layer_write_unattended, which differ solely in approval mode, but the descriptions explicitly state when to use each, mitigating confusion.
All tools use snake_case with a predictable verb_noun (or verb_resource) structure: connect_database, execute_sql, check_connection, get_schema_info, execute_service_layer, and the consistent _write / _write_unattended suffixes. No mixed conventions.
Seven tools is well-scoped for a database + Service Layer bridge: connection, health, schema, SQL read, SL read, SL write, and unattended write. Each tool earns its place; nothing feels redundant beyond the necessary approval-mode split.
The surface covers the full read lifecycle (connect, check, schema, SQL, OData GET) plus guarded writes, with the deliberate and documented omission of raw SQL writes. The main gap is the lack of Service Layer metadata/entity-set discovery analogous to get_schema_info, which would help agents construct valid OData requests.
Related MCP Connectors
Read, write and run Odoo actions from any AI app, as each user, with approval rules per colleague.
Company and industrial data for AI assistants: datasets, SQL, dashboards, alarms, with approvals.
Work with your database from AI tools: ask, export, approved changes, and scheduled jobs.
Read and write Sage Intacct from Claude or ChatGPT. Write tools are flagged for approval.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables interaction with SAP Business One via Service Layer REST API to retrieve and create business data such as partners, orders, invoices, items, and stock levels through natural language.1-
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to discover SAP B1 entities, inspect their schemas, and perform authenticated CRUD operations through natural language, translating requests into Service Layer API calls.148 npmMIT
- AlicenseNot gradedqualityNot gradedmaintenanceConnects SAP Business One to Claude, ChatGPT, and Copilot, providing 12 MCP tools to read business partners, items, sales orders, invoices, quotations, and delivery notes, and to create sales orders.AGPL 3.0
- AlicenseNot gradedqualityBmaintenanceEnables an AI agent to read and query SAP OData services and SAP Business One Service Layer data such as business partners, products, items, sales and purchase orders, and invoices, plus gated creation and updates. Writes are disabled by default, support dry-run payload preview, and are verified by an independent read-back, with credentials kept out of tool arguments and local mocks allowing the whole stack to be exercised without a SAP account.1MIT