AI Agent Access (MCP Server)¶
The MCP server lets an external AI client such as Claude Code, Codex, or any other Model Context Protocol host, connect to a running AmiCore instance and operate it through tools. The client discovers the available 3forge Enterprise operations, then calls them by name to inspect and drive the deployment.
The server is an Enterprise plugin that runs inside the component and exposes an authenticated HTTP endpoint on Enterprise's REST surface (the Web port by default) or REST's own socket if the deployment moves it (see Enabling and configuring).
What Gets Exposed¶
Enterprise's console operations become MCP tools. Every component (Center, Web, Relay) and cross-component utility (logs, documentation) registers its operations at startup, so a single connection can reach all of them.
Tools are named by their owner so one client can talk to the whole deployment:
The component prefixes are center_, web_, and relay_; cross-component utilities use their frame key (log_, ami_, aidoc_, …).
Grouped Operations and the op Selector¶
Most operations are grouped: rather than one tool per operation, related operations share a tool and are selected with a required op parameter. Reading a panel list and deleting a panel are both Web operations, but they live in different tools because they carry different risk:
| Tool | Selected with | Holds |
|---|---|---|
web_console |
op=panels, op=sessions, op=tableColumns, … |
Read-only introspection |
web_execute |
op=importWindow, op=updatePanel, … |
Layout and datamodel mutation |
web_danger |
op=deletePanel, op=killSession, … |
Destructive operations |
web_verify |
op=panelJson, op=datamodel, op=script |
Validation before applying |
Each tool's schema lists its valid op values and the parameters each one takes, so a client discovers them the same way it discovers any tool. A call with a missing or unknown op is rejected with the valid list.
Not every operation is grouped. Some remain standalone tools, such as relay_addFeedhandler and web_script.
Note
When a deployment runs more than one component of the same type (e.g: 2 Centers), tools accept an optional componentId parameter to choose which instance to target. With a single instance of a type, it can be omitted.
Enabling and Configuring¶
The MCP server is a REST plugin with the id MCP, served by the Enterprise REST server at /3forge_rest/mcp. Where that path is served is decided by ami.rest.uses.web.port, which ships as web, so on a default install the endpoint is on the Web component's ports: https://<host>:33333/3forge_rest/mcp.
REST plugins are loaded via the ami.rest.plugin.classes property. By default, it includes every discovered plugin except the canonical query/admin endpoints:
Because MCP is matched by the *, it is enabled by default . To disable it, add !MCP to the list in local.properties:
| Property | Default | Purpose |
|---|---|---|
ami.rest.plugin.classes |
*,!QUERY,!ADMIN |
Which REST plugins load; !MCP disables this endpoint |
ami.rest.uses.web.port |
web |
Which Web component's port serves REST. false moves REST to its own socket instead (below) |
ami.mcp.tools.disabled |
(empty) | Comma-separated blacklist of tool names; supports prefix_* wildcards |
Moving REST off the Web port¶
ami.rest.uses.web.port decides where the whole REST surface, /3forge_rest/mcp included, is served. It uses the named Web component's own http.port / https.port values by default.
To bind REST to its own socket instead, set it to false and provide an alternative free port:
Note
ami.rest.http.port has no shipped default, so the REST socket only exists once you choose a port for it. 8766 above is an example, not a default.
On a trusted, closed network, a dedicated plain-HTTP REST port lets MCP clients connect without any TLS setup, while the Web port keeps serving the browser over HTTPS. Do not use it on an untrusted network: Basic credentials and every response travel in clear text. It is one or the other, not both. Moving REST off the Web port means https://<host>:<https.port>/3forge_rest/* stops answering, and any other client of the REST surface has to be re-pointed too.
The tool catalog is built lazily on the first request, so every component has finished registering before any tool is resolved.
Restricting the Tool Set¶
To hide operations you do not want an agent to reach, for example all Relay mutators, list them in ami.mcp.tools.disabled:
Matching is on the tool name, and a disabled tool is dropped at registration so it never appears in tools/list.
Warning
This property cannot disable a single op. Naming a grouped tool disables every operation in it, and naming an operation such as web_killSession matches nothing at all, because the tool is web_danger and killSession is one of its op values. To take away one operation of a group and keep the rest, use an agent allowlist instead: see Agents and their tool allowlists.
Authentication¶
The MCP tools are high-privilege (SQL execution, component management, layout deployment), so every request is authenticated by the REST server before the plugin runs. 2 schemes are accepted, tried in this order:
- Web session. If the request carries an active Web session, the session cookie set when a user logs into the Web component in the browser, the request runs as that logged-in user. No credentials are sent on the request itself; it rides on the existing browser login. This is the path taken when the endpoint is called from within an authenticated Web session on the same host.
- HTTP Basic. Otherwise, the caller supplies an
Authorization: Basic <base64(user:pass)>header. The username and password are verified against the Web REST authenticator (auth namespaceamiweb_rest), the same user store as Web login. This is the scheme an external MCP client (Claude Code, Codex) uses, since it has no browser session.
The header value is the base64 encoding of username:password:
The request outcome depends on the result:
| Result | HTTP status |
|---|---|
| Authenticated (session or valid credentials) | request proceeds |
Missing Authorization header and no web session |
401 (with WWW-Authenticate: Basic) |
| Invalid username or password | 401 |
| Account locked, service disabled, or user-count exceeded | 403 |
The resolved user is the identity every tool call runs as, so a caller only reaches operations their entitlements permit.
Connecting a Client¶
Point an MCP server entry at the endpoint on the web port, and supply credentials. For Claude Code / Codex:
typemust behttp, because the endpoint is a plain HTTP JSON-RPC transport (below), not the SSE or stdio transports some clients default to. Omitting it is the most common "it will not connect" cause.urlis the REST endpoint on the web port: thehttp.portfor plain HTTP, or thehttps.portfor TLS.headers.Authorizationcarries the Basic credentials.
Over HTTPS with the default self-signed certificate you must also configure the client to trust it. See Transport security below; a config with only type / url / headers connects over plain HTTP but is rejected over TLS until trust is set up.
Transport is plain request/response: the client POSTs a JSON-RPC 2.0 request and reads the JSON-RPC response. A GET is declined with 405 (there is no server-initiated event stream).
The Authorization value is reversible Base64, not a secret
Basic <base64(user:pass)> is a trivially decodable encoding, not encryption. Anyone who reads the header recovers the password. Send it only over a trusted transport (TLS, or a closed network), and never commit a config file carrying production credentials; use a placeholder and inject the real header at deploy time.
Once connected, the client lists the Enterprise tools and can call them by name (center_execute, web_console with an op, and so on). The server's handshake includes an instructions string pointing the agent at the built-in reference. The agent can call get_documentation("admin") for the full tool reference, or get_documentation() with no argument to list all reference topics.
Transport Security and Self-Signed Certificates¶
The endpoint is served on the Web listeners. The web component can serve plain HTTP, HTTPS, or both, configured in its local.properties:
| Property | Purpose |
|---|---|
http.port |
Plain-HTTP listener port |
https.port |
HTTPS listener port |
https.keystore.file |
Keystore (Java keytool format) holding the server certificate and private key |
https.keystore.password |
Password for that keystore |
Set the keystore password for your deployment
The shipped defaults.properties sets https.keystore.password=${ami.keypass}, so the effective keystore password is whatever ami.keypass resolves to. Override ami.keypass, or https.keystore.password directly, before the instance is reachable by anyone else. See Security Defaults.
Self-signed certificate: 2 things must hold
Enterprise ships a self-signed certificate in the default keystore. Over HTTPS a validating MCP client, as most are, needs both of the following, or it refuses to connect:
- The client must trust the certificate. It is self-signed, so no CA vouches for it, and the client has to be told to trust it explicitly.
- The certificate's name must match the URL host. If the certificate carries no Subject Alternative Name matching the host you connect to, the client rejects it with
ERR_TLS_CERT_ALTNAME_INVALID(hostname mismatch) even after it is trusted. The HTTPS listener still starts normally, and the failure is entirely client-side. Trusting alone is not enough. Contact 3forge support for the specifics of the certificate shipped with your build.
3 ways to satisfy both requirements:
- Move REST onto its own plain-HTTP port, by setting
ami.rest.uses.web.port=falseand choosing anami.rest.http.portas described above, then connecting tohttp://<host>:<amiRestHttpPort>/3forge_rest/mcp. This sidesteps certificate validation entirely, so confine it to a trusted, closed network: Basic credentials and every response travel in clear text. The Web HTTP port is not an option here: with TLS enabled by default it redirects to the HTTPS port. -
Regenerate the keystore with a SAN that matches your host. For example, to reissue a cert valid for
localhost/127.0.0.1(add your real deployment hostname to theSANlist as needed): -
Install a CA-signed certificate (recommended for production): point
https.keystore.file/https.keystore.passwordat a keystore whose certificate is issued by a trusted CA for your real hostname. Both requirements are then met by the CA chain and the cert's SAN.
Replacing the server certificate is a server-side task shared by every client, not just MCP. See Server Certificates for the full procedure.
Trusting the Certificate in the Client¶
A client trusts the public certificate, not the keystore (the keystore holds the private key, so never distribute it). Export the certificate to a PEM first, because Enterprise does not ship one:
For a Node-based MCP client (many editor-hosted clients are Node), point NODE_EXTRA_CA_CERTS at that exported PEM so Node adds it to its trust store:
A JVM-based client instead imports it into a truststore (keytool -importcert) referenced by -Djavax.net.ssl.trustStore. Either way requirement 2 still applies: the exported certificate must carry a SAN matching the host in the client's url, or trust succeeds but the hostname check still fails.
Verifying It Is Running¶
On startup the plugin logs a line confirming the endpoint is live:
A connecting client confirms the endpoint by completing the MCP initialize handshake and listing tools.
Results and Errors¶
Tool results are serialized to JSON: tables come back as row arrays, scalars and maps as their natural JSON. A failed tool returns an error object rather than a transport fault, so the calling agent can read the message and adapt:
Warning
The MCP server grants an authenticated external process the ability to operate your Enterprise instance. Bind the web port to a trusted network, restrict the exposed tool set with ami.mcp.tools.disabled, and connect with an identity whose entitlements match what the agent should be allowed to do.
Related¶
- 3forge MCP Plugin for AI Coding Tools: a ready-made client plugin (Claude Code, Codex, Copilot) that connects to this server with 3forge skills, agents, and commands.
- Mandatory Mutual TLS: the client-certificate allowlist enforced on the Center, JDBC, Relay, and Gateway listeners. It does not apply to the Web listener that serves this endpoint, which authenticates with HTTP Basic instead.
- Ask AI Chatbot -> agents and tool allowlists: narrowing what a single agent may call, beyond the server-wide
ami.mcp.tools.disabled.