# MCP Server

Tediware hosts a Model Context Protocol server at `POST /mcp`. Its tools cover the same ground as the REST API and the `tedi` CLI, with the same API key, the same rate limits, and the same service terms as every other endpoint: interchange inspection and reading and driving your own EDI traffic.

The server implements MCP revision `2026-07-28`, which is stateless: no `initialize` handshake, no session id, no long-lived connection. Every call is a single HTTP POST.

## Connecting

Configure your MCP client with the endpoint URL and your API key as a header:

```
URL:     https://tediware.com/mcp
Header:  Authorization: Key your-api-key-here
```

Every request also needs the transport's own headers, which conforming clients send for you:

```
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: transaction_list
```

The server checks that those headers match the request body and rejects the call with JSON-RPC error `-32020` if they do not. The headers are what the rate limiter meters on, so a request that disagrees with itself cannot be metered correctly and is not accepted.

Only standard API keys work here. A sandbox key is rejected with `403`.

## Discovering the surface

`server/discover` reports the supported protocol versions and capabilities. `tools/list` returns the tools. Both are cacheable by the client (`ttlMs`) and never by a shared cache (`cacheScope: private`).

```bash
curl -X POST https://tediware.com/mcp \
  -H "Authorization: Key your-api-key-here" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/list" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list",
    "params": {
      "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28" }
    }
  }'
```

## The tools

Every tool maps onto an endpoint documented elsewhere in this reference, so the scoping, filters and error meanings are the ones described there.

```
X12 releases and inspection
  x12_releases           The release codes this server carries
  edi_inspect            Decode and validate a document

Your EDI traffic (structured)
  whoami                 Which organization this key belongs to
  transaction_list       List EDI transactions
  transaction_get        One transaction in full
  transaction_logs       The processing log for a trace
  transaction_resend     Re-deliver an outbound transaction
  trace_get              One processing run, assembled
  result_list            List processing results
  result_get             One result
  feed_list              The forward feed of documents and errors
  artifact_get           One artifact's document

Your configuration (structured, read-only)
  partner_list           List partners and what each exchanges
  partner_get            One partner: connection, envelopes, webhooks, sets, flows
  connection_list        List connections
  connection_get         One connection and the partners on it
  envelope_list          List envelopes
  envelope_get           One envelope and the partners using it, with role
  webhook_list           List webhooks
  webhook_get            One webhook and the partners delivering to it, with role
  flow_list              List flows, filtered by partner, direction or status
  flow_get               One flow with its nodes and edges
  mapping_list           List mappings and the partners using each
  mapping_get            One mapping with its current version and source
  mapping_versions       The versions of one mapping
  implementation_list    List your own implementations
  implementation_get     One implementation and what points at it
  implementation_schema  The JSON schema a mapping targets
  implementation_guide   The rendered guide (text only)
  source_list            List sources
  source_get             One source with its sample

Submissions
  partner_send           Submit an outbound document
  partner_receive        Submit an inbound EDI document
```

### Releases and inspection

`x12_releases` returns the release codes as structured data. `edi_inspect` returns its report as text and, as structured fields, the finding counts (`errors`, `notices`, `complete`) matching the headers the HTTP inspector sets, plus `findings`: each one's severity, code, title, details, and the line and segment it cites, in document order.

`implementation_guide` returns the rendered guide as one text block, Markdown by default, and no `structuredContent`. The structure as data is `implementation_schema`, the JSON schema a mapping targets.

### Data tools answer with structured content

The data tools return `structuredContent` in the same shape the REST endpoints return, including the `pagination` envelope with `hasMore` and `nextCursor`. It is your own data, so structured access is the point. The text block beside it is a one-line summary (the kind of record, its id, its status) rather than the same JSON again.

The configuration tools (the `partner_*`, `connection_*`, `envelope_*`, `webhook_*`, `flow_*`, `mapping_*`, `implementation_*` and `source_*` tools) are in preview, as are the [Partners](/resources/api-docs/partners) and [Configuration](/resources/api-docs/configuration) endpoints. Their output shapes may change without notice. `partner_send` and `partner_receive` are submissions, not configuration reads, and are not in preview.

`edi_inspect` and `partner_receive` send your document to the server. Scrub identifiers or personal data out of a document before an agent submits it: there is no local scrubbing step inside a hosted tool. `tedi edi obfuscate` is that step, and it runs entirely on the caller's machine.

## Arguments

Tool argument names are camelCase, matching the REST query parameters and the keys the tools return: `transactionSetIdentifier`, `ackStatus`, `transactionId`, `partnerKey`.

Arguments are validated against each tool's schema before the tool runs, and every schema declares `additionalProperties: false`, so an unknown or misspelled argument is a refusal rather than a filter that silently did nothing. Three rules follow from the same principle:

- An empty string for an identifying argument (`trace`, `partner`, `transactionId`, `node`) is an error, not "no filter". A blank shell variable should not return your whole organization.
- `direction` and `status` declare their allowed values and refuse anything else with the list, as `ackStatus` and `level` do. `warnings` on `transaction_list` is a boolean: `true` for transactions with at least one warning.
- A `limit` outside 1 to 100 is an error rather than a silent clamp.

## Write tools

`transaction_resend`, `partner_send` and `partner_receive` are annotated `readOnlyHint: false` so an agent framework can require confirmation before running them. `transaction_resend` also carries `destructiveHint: true`: an accepted resend puts a duplicate document on your trading partner's wire.

All three queue work rather than completing it inline. A successful call means processing started. Follow the returned `traceGuid` with `trace_get`, which carries a `processing` boolean so a polling agent has a defined end.

## Errors

Two kinds, and the difference is who can act on them.

**Tool errors** come back as an ordinary result with `isError: true` and a message in the text block: a record that does not exist, a document that will not parse, a filter value out of range. An agent can read these and try again.

**Protocol errors** come back as JSON-RPC errors with an HTTP status:

```
401  -32000  Missing or invalid API key
403  -32000  Organization disabled, sandbox key, or service terms not accepted
400  -32020  Headers disagree with the request body
400  -32022  Unsupported protocol version (the error lists the supported ones)
400  -32602  Unknown tool
404  -32601  Unknown method
400  -32700  The body is not valid JSON
500  -32603  An unhandled fault on the server, carrying your request id
```

The `403` cases carry a `data.reason` naming the specific condition: `organization_disabled`, `sandbox_key_not_supported`, `service_terms_required`.

## Connecting a stdio client

Most MCP hosts launch a server as a subprocess over stdio rather than calling an HTTP endpoint, and most of them still open with the older `initialize` handshake this revision removed. A host that sends that handshake straight to `/mcp` gets a `-32020` error naming the bridge below; it is not a credential problem. `tedi mcp serve`, from the [tedi CLI](/tools/cli), bridges both gaps: it answers the handshake locally, stamps this revision onto everything it forwards, and uses the key from `tedi auth login` so one never has to be written into an agent's configuration file.

```bash
claude mcp add tediware -- tedi mcp serve
```

The bridge holds no tool logic. It forwards every request, so the tool list and descriptions you see through it are the server's own.

The in-app help assistant uses the same tools: signed in, it runs the read-only ones above (the configuration and traffic reads, never the submissions) as the signed-in user, so what it tells you about a partner or a trace is what these tools return.

## Rate limits

MCP calls count against the same ceilings as the equivalent HTTP endpoints, not separate ones. `x12_releases` spends the same reference allowance an `/api/x12` read spends; `edi_inspect` spends the inspection allowance; the data tools spend the platform allowance; `transaction_resend` meets the resend ceiling. See [Platform Limits](/resources/docs/platform-limits).
