forge_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., "@forge_mcpstart a run on cnc-01 and tell me whether the part came out good"
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.
forgekit
One typed Python SDK over the three internal services that run a manufacturing floor, and an MCP server on top of it, so an engineer or an agent can say "start this run on cnc-01 and tell me whether the part came out good" and get an answer that is true, or an honest "unknown, ask a person" when the two systems that hold the answer disagree.
The platform, and the problem
The platform team reverse-engineered a floor of instruments, CNC mills, a robot arm and SLS printers, into API-controllable machines. Their engineers, and increasingly their agents, run production jobs through three internal services, each written by a different team at a different time:
service | what it holds | authentication | pagination | error shape |
orchestration | work orders, the lifecycle state machine, dependencies | bearer token |
|
|
machine control | the machines, runs (long-running), abort, purge, key attenuation | API key header, scoped |
|
|
production data | results, QC records, telemetry | token in the query string | cursor | plain text |
Consuming them is miserable. A new hire spends a week learning which service wants which header,
which page shape and which error body, and agents are worse at it than people. The published
OpenAPI document is behind the code: it names a field state that is live as status, documents
run dispatch as synchronous when the live endpoint answers 202 with an id to poll, describes 4
of the 17 live endpoints, and omits the whole production-data service.
Two things about the floor make this harder than plumbing. A machine run takes fifteen to forty minutes. And some machine operations are destructive: abort a running job, purge a queue. An agent holding the wrong credential can stop a live cut.
Related MCP server: CrewAI Enterprise MCP Server
What was tried before, and why it failed
An in-house wrapper existed before this work. It read the OpenAPI document and generated one MCP tool per endpoint, about forty flat tools, all authenticating with the master admin key baked into the server configuration, with "start a run" implemented as a tool that blocks and polls until the run finishes.
It failed on the floor in three ways, each observed rather than predicted. The agent picked the wrong tool constantly, because forty near-identical verbs with no shape between reads, writes and destructive actions is not a surface anyone can choose from. The blocking start-run tool sat there until the client killed it on a real mill run, and the agent then reported the run as failed while the spindle was still cutting. And a teammate's agent, asked to "clean up cnc-02", went looking for a purge tool and found one, on the admin key.
Two instincts were on the table for fixing it, and both are wrong in ways worth stating, because they are what a competent engineer reaches for first. Regenerating the tools cleanly from the OpenAPI document produces a surface that is still too large to choose from and still wrong, because the document is wrong, and it re-rots at the next drift. Using MCP roots to keep the agent away from destructive operations fences nothing, because roots are advisory to a client, not an authorization decision a server can rely on.
The platform team's concerns, and what this does about each
Their four concerns, in their order, and the mechanism that answers each one. Every mechanism is one a test attacks rather than a paragraph that asks to be believed; the test named beside each is the one to read first.
the concern | what this does | where |
Long-running work. A run is fifteen to forty minutes; a tool that waits for it times out, and a dropped connection loses the only handle to a run that is still cutting | Call-now, fetch-later. |
|
Safety. Everything ran under the admin key; an agent could abort a live job or purge a queue | The credential, not the prompt. At boot the server spends the master key once to mint an attenuated child key without |
|
Not one tool per endpoint. Forty flat tools, the agent picks wrong | A curated, mechanically split surface: a state-changing endpoint is a tool, a read-only endpoint is a resource, a fixed workflow is a prompt. Applied to all 17 live endpoints the map comes to four agent tools, five admin tools, a twelve-entry resource tree and five prompts, and nothing falls off it: reads change shelf, so they stop competing with actions for the agent's choice. Built in this phase: |
|
The mess itself. Three auth schemes, three paginations, three error shapes | One SDK. One HTTP seam above which nothing knows which service it is talking to; three auth strategies behind one interface, each redacting itself in |
|
Two more things the brief did not name as concerns and the work made unavoidable:
The OpenAPI document is not the platform. Every statement this repository makes about the three services came from a live probe of staging, and each is pinned by a contract test that runs against staging with no mocks: 59 collected, in two marker groups, so a red is legible.
contractmeans something this depends on broke;pinned_defectmeans a known platform defect changed and someone should look. A fix and a regression look identical to an assertion, which is why they are separated (tests/contract)."The run finished" and "the part is good" are two facts in two systems. Orchestration says
done; the QC bench sayswall_mmcame in under spec. A wrapper that reports lifecycle status says the part is good, and ships it.RunVerdictjoins the two reads and derives its conclusion rather than accepting one, refuses to judge one run by another run's QC record (test_a_result_from_another_machine_is_refused), and answersunknownout loud when the join is not safe (src/forge_sdk/verdict.py,src/forge_sdk/models.py).
The shape of it
agent · engineer · CI job
│ MCP over Streamable HTTP, loopback bind, Host and Origin checked
▼
┌────────────────────────────────────────────────────────────────────┐
│ forge_mcp │
│ tools start_run get_run_status │
│ resources forge://runs/ forge://runs/{task_id}/status │
│ │
│ ┌─────────────────┐ ┌───────────────────┐ ┌─────────────────┐ │
│ │ SqliteTaskStore │◀──│ RunTracker │ │ ReadOnlyTaskDao │ │
│ │ one writer per │ │ poll the run, join│ │ what resources │ │
│ │ file, refused │ │ the QC record, │ │ read through; │ │
│ │ at startup │ │ write the verdict │ │ no write method │ │
│ │ │ │ re-dispatch │ │ │ │
│ │ │ │ nothing, ever │ │ │ │
│ └─────────────────┘ └─────────┬─────────┘ └─────────────────┘ │
└──────────────────────────────────┼─────────────────────────────────┘
│ the child key: minted at boot from the master key, without
│ run:abort or machine:purge; boot refuses if the mint came
▼ back with either scope
┌────────────────────────────────────────────────────────────────────┐
│ forge_sdk │
│ machines (four guards) data (the QC read) keys (mint, assert) │
│ └──────────────────┬───────────────────┘ │
│ ServiceClient: one HTTP seam │
│ auth ×3 pagination ×3 error decoder ×3 │
└──────────────────────────────────┬─────────────────────────────────┘
▼
┌────────────────────────────────────────────────────────────────────┐
│ the platform: one host, three services │
│ /orchestration/v1 /machines/v2 /data │
│ Bearer X-API-Key, scoped ?api_token= │
│ limit / offset page / page_size cursor │
│ {"error": {...}} {"detail": "..."} plain text │
└────────────────────────────────────────────────────────────────────┘
▲ 59 contract tests, live against staging, no mocks ▲Not drawn: the admin surface, designed and not built, which will carry abort_run,
purge_machine, cancel_work_order, approve_rerun, reconcile_orphan and the audit resource
on a key of its own. Until it exists nothing on this server reaches a destructive operation, and
the reason is the credential in the middle of the picture rather than the absence of a tool.
The second phase, and where it stands
The platform team's internal assistant answers questions about jobs and machines and can only talk; the point of the surface above is that it can act through it: start a run, stage a re-run with the reason attached for a person to dispatch, say what a stuck job is waiting on. The brief for that phase is explicit about what would not convince them that it works: one clean question on a healthy platform. What they worry about, in their order: an operator who asks badly at a shift change; the floor changing under an answer, a machine dropping offline, a slow data service, a stale read that says a machine is available when it is in maintenance; the assistant saying a job is fine when it is not; and the thing quietly getting worse after someone edits a prompt.
forge_assistant is that thin assistant, acting through the MCP server and kept from destructive
operations by the same credential the agent surface holds. forge_eval is the evaluation
substrate that grades what it does: cases, a corpus, a judge with an agreement gate against
hand-labelled expectations, outcomes scored per skill and per failure mode. Both are exercised by
the unit tier with no key and no network. Both are wired to a live model through the assistant extra (claude-agent-sdk==0.2.140, the release that co-installs with this project's mcp pin; pyproject.toml records the history beside it), and the wiring is exercised by the model tier under tests/model: twelve tests, gated on FORGE_LIVE_MODEL=1, a key and the platform running, that boot this server as a subprocess, run real turns through a real client and read what happened off the server's own log, the task database and the transcript. The judge sits in a different model family from the assistant, on purpose. What ships today is the client library and those tests; an operator-facing entry point for the assistant is not built yet. The position that fixes the assistant's boundary is
docs/design/2026-08-15-agent-sdk-boundary-position.md.
What is here
count | what it counts | |
source | 38 modules, 7,357 lines | every |
unit tests | 648 passing, 1 skipped | recorded transports and one real loopback socket; no staging, no credential |
contract tests | 59 collected | live staging, no mocks, two marker groups |
integration tests | 6 collected | live staging, except one that monkeypatches the mint |
A fifth tier under tests/model, twelve tests, drives the assistant against a live model and is not
part of these counts; it needs a key, the platform and the assistant extra.
The one skip is the POSIX file-lock branch, skipped on Windows with the platform gap named in the
skip reason (test_on_posix_the_lock_is_advisory_and_does_not_block_io); the Linux CI job is
where it runs.
Run it
The unit suite, with no staging and no credentials:
python -m pytest tests/unit -qThe contract suite, against staging:
set FORGE_BASE_URL=http://your-staging
python -m pytest tests/contract -qOne contract test is gated behind FORGE_STAGING_EXCLUSIVE=1 because it mutates global platform
state; the default tier creates only prefix-tagged records and cancels them at teardown, because
staging is shared with the people who work there.
The documentation-honesty checks, which every push runs in CI in --strict mode:
python tools/guarantee_lint.py
python tools/predicate_lint.pyA sentence in the scanned documents that promises a property of the code is compliant when it names a test that resolves, or carries a reviewed note giving the reason no test applies. What the tool checks is that the name resolves; whether the cited test attacks the sentence it sits under is a review question, and six citations resolved and covered nothing before a review caught them. Both tools report how many files they examined and refuse to pass on zero.
Connect a client
set FORGE_MACHINE_KEY=...
set FORGE_DATA_TOKEN=...
forge-mcpThen point a client at http://127.0.0.1:8831/mcp. .mcp.json at the root of this repository
does that for anyone who opens it in Claude Code, and claude mcp add --transport http forge-robotics http://127.0.0.1:8831/mcp does it for one person. docs/connecting.md is the full
version: the seven environment variables, what boot prints, and how to confirm the client
connected rather than assuming it did. The two credentials have no defaults and the server refuses
to start without them, naming the missing variable; a deployment that forgot one used to come up
green against the wrong estate.
Nothing authenticates a client to this server in this phase. Every credential above is spent on
the hop from this server to the platform; on the hop from a client to this server there is no
token, and any process on the host can call start_run. The bind stays on loopback and the
endpoint validates Host and Origin against an allowlist derived from it. The fence for that hop
is the OAuth tier, designed against the platform's identity service and not built; section 8.9 of
the architecture note states it in those words.
Where to read
docs/background.md: the floor, the brief in the platform team's own terms, what was tried and failed, and the concern-to-mechanism map with what a reader checks for each.docs/map/phase0-surface-map.md: the client-facing surface map, what is built and what is designed, with the table of sentences that once claimed more than the code delivered and how each was found.docs/connecting.mdanddocs/handover.md: starting the server, pointing a client at it, and the transcript of that being done end to end.docs/architecture/forge-sdk-architecture.md: the long-form architecture note, the rejected alternatives, the failure taxonomy, the threat model.docs/design/2026-07-26-forge-sdk-mcp-design.md: the design of record, with the dated amendment that removed MCP tasks from the surface.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
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 Connectors
Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.
The AI orchestration agent for modern software teams.
Workflow planning, recovery checkpoints, coordination, fixtures, and compatibility tools for agents.
Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables automated LLM red teaming by submitting asynchronous test runs, retrieving aggregated metrics, and accessing artifacts.4CC BY-SA 4.0
- -licenseNot gradedqualityNot gradedmaintenanceEnables kicking off deployed CrewAI workflows and inspecting their status and results.-
- AlicenseNot gradedqualityBmaintenanceEnables managing persistent AI workers through MCP tools for versioning, safe testing, deployment, approvals, and run lifecycle with tenant isolation and policy enforcement.5Apache 2.0
- AlicenseAqualityBmaintenanceEnables AI agents to safely inspect and execute version-controlled operational runbooks with policy checks, dry-run planning, and out-of-band approvals.3MIT
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/EsraaKamel11/forgekit'
If you have feedback or need assistance with the MCP directory API, please join our Discord server