Skip to main content
Each Fortress agent connects to the MCP server with its own scoped URL. Most local clients use a bearer token; OAuth-capable remote clients can use Fortress’s OAuth flow.
https://api.fortressproductivity.com/mcp?agent_id=<agent-id>
Authorization: Bearer ft_...
Local development uses the API origin running on port 3000:
http://localhost:3000/mcp?agent_id=<agent-id>
Authorization: Bearer ft_...

Server identity

FieldValue
Namefortress
TitleFortress
DescriptionMission control for a human and their bring-your-own agents.
TransportHTTP MCP endpoint
AuthBearer token or OAuth access token scoped to one agent

Resources before tools

Agents should use resources for reads when they know the URI. Tools are for writes, search, or reads that need parameters such as a limit.

Read full context

Use fortress://action/<id>, fortress://project/<id>, and fortress://document/<id>.

Mutate state

Use tools such as heartbeat, complete_action, drop_action, ask_question, and update_document.

Required startup reads

At the start of a session, an agent should read:
  1. fortress://workspace/overview
  2. fortress://orders
  3. fortress://order/<id> for any active order it will execute
  4. fortress://action/<id> before doing a task

Error handling

MCP tool errors return structured content under structuredContent.error. The shape is:
{
  "structuredContent": {
    "error": {
      "code": "already_terminal",
      "message": "Action is already complete."
    }
  }
}
Agents should branch on the stable code field, not natural-language messages. Examples include:
CodeMeaning
already_terminalAnother actor already completed or dropped the action. Refetch and stop retrying.
not_agent_actionableThe action is no longer ready work for this agent.
wrong_actorThe token does not match the actor allowed for the operation.
template_not_completableTemplate actions cannot be completed as live work.
TOO_MANY_IDSA batch read such as get_actions exceeded the 100-id cap. Split the request and retry.

Uniform error boundary

The same structured envelope is enforced across every MCP surface — tools, prompts, resources, and elicitation responses. Unexpected server failures and elicitation rejections are caught at the MCP boundary and returned as a structured error with a stable code instead of an opaque transport-level 500. Agents can rely on parsing structuredContent.error.code for any failure path, including ones that previously surfaced as raw HTTP errors.

Transport status codes

When a request cannot reach the structured envelope at all, Fortress picks an HTTP status that reflects the real failure category instead of collapsing everything into 401 or 500. Agents and orchestrators can use the status to decide whether to refresh credentials, retry with backoff, or surface the failure to the operator.
StatusMeaning
401The bearer token or OAuth access token is missing, expired, or scoped to a different agent. Re-authenticate before retrying.
404The mcp-session-id is no longer live. The error envelope carries data.details.reason so the agent can branch on the typed reason instead of retrying the same request — see Session lifecycle.
503A transient backend dependency failed — for example, database or KMS unavailability during session init, or an upstream option-fetch timeout while resolving an elicitation. Retry with backoff.
5xxAn internal MCP client received a non-JSON upstream response. The original status and a body preview are preserved in the error message instead of being rewritten to 500, so logs reflect what the upstream actually returned.

Session lifecycle

Long-lived agents (Claude Code in a persistent shell, scheduled-job runners) regularly outlive their MCP session. Fortress sweeps idle sessions after MCP_SESSION_MAX_IDLE_MS (default 30 minutes), evicts the oldest sessions when concurrent sessions exceed MCP_MAX_SESSIONS (default 40), and honors client-initiated DELETE closes. Any subsequent request bound to a closed session returns a JSON-RPC -32001 404 with structured data.details:
{
  "jsonrpc": "2.0",
  "id": 42,
  "error": {
    "code": -32001,
    "message": "Unknown MCP session",
    "data": {
      "details": {
        "reason": "idle_timeout",
        "hint": "reinitialize the MCP session"
      }
    }
  }
}
reason is one of:
ReasonCause
idle_timeoutThe session was swept after exceeding MCP_SESSION_MAX_IDLE_MS of inactivity.
session_capThe session was evicted as the oldest entry once concurrent sessions hit MCP_MAX_SESSIONS.
client_closedThe client itself closed the session (e.g. an MCP DELETE against the session id).
unknownThe session id was never recognized — typically a misconfigured or replayed agent header.
Agents should treat any of these as a signal to send a fresh initialize and replay the request against the new session id, rather than retrying the same request on the closed id. Mutation tools always commit before projecting their response. If a mutation succeeds but the follow-up read drifts (for example, a stale read replica), the tool still returns success and the drift is reported separately so agents do not retry an already-applied write.

Response shape guarantee

Every tool that publishes an outputSchema is contractually bound to it. Composite tools — the mutation-then-projection tools that return a freshly read view alongside the write — validate their projected payload against the declared schema before responding. A projection that would otherwise drift off-schema (extra, missing, or wrong-typed fields from a stale read) is rejected at the boundary and surfaced through the standard structured error envelope rather than being passed through to the agent. Agents can rely on structuredContent matching the documented outputSchema on success, so generated clients and typed parsers do not need defensive fallbacks.

Failure analytics

Every MCP tool failure is also tagged in Fortress analytics with the same error_code that appears in the structured response. Operators reviewing telemetry can group failures by error_code to see which codes (for example, already_terminal versus wrong_actor) drive the bulk of agent retries, without parsing free-text messages.

Subscriptions

The MCP server supports resource subscriptions. Subscribable resources include actions, questions, projects, orders, and the authenticated agent’s own queue. Use subscriptions when an agent runtime stays alive and should react to queue changes or question answers.

OAuth clients

Fortress also exposes OAuth 2.1 flows for MCP clients that discover and register dynamically. The consent page can use the agent_id hint in the MCP resource URL to preselect the intended agent.