All sections

Advanced

MCP server

On this page

Tetiva ships an MCP server called Tetiva DevTools. It exposes 32 tools that let an AI agent read your workspaces, collections, requests and environments, create new ones, and run a saved request with the same environments, scripts and history you get from pressing Send. Nothing has to be pasted into a chat: the agent talks to the app at 127.0.0.1:9300.

The server advertises tools only — no resources, no prompts — and it lives exactly as long as the app window does.

Turning it on#

Open settings (Cmd/Ctrl+,, or the gear at the bottom of the left bar) and find the MCP / DevTools section:

  1. Flip Enable.
  2. Check Port / address127.0.0.1:9300 by default.
  3. Restart the app. The section shows "Restart required to apply"; the server binds at startup.

After the restart the Status row reads ● Running and the SSE endpoint is printed next to it.

MCP can also be driven by environment variables: TETIVA_MCP=1 enables the server and TETIVA_MCP_ADDR sets the address. The pre-rebrand names GOPHERCOURIER_MCP and GOPHERCOURIER_MCP_ADDR still work. When either is set, the settings fields lock and read "Managed by environment variables".

Connecting an agent#

The server asks for an access token. Copy config in settings puts a ready-made snippet on the clipboard for the client you pick — Claude Desktop, Cursor, or the bare URL — with the token already in it. For clients whose config holds nothing but a URL, the token rides in the query string:

{
  "mcpServers": {
    "tetiva": {
      "url": "http://127.0.0.1:9300/sse?token=YOUR_TOKEN"
    }
  }
}

Cursor can send headers, which keeps the token out of the URL:

{
  "mcpServers": {
    "tetiva": {
      "url": "http://127.0.0.1:9300/sse",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

Claude Code takes the same endpoint in one command:

claude mcp add --transport sse tetiva http://127.0.0.1:9300/sse \
  --header "Authorization: Bearer YOUR_TOKEN"

The copy button next to the token in settings puts the raw value on the clipboard, which is what this command wants; Copy config gives you a whole snippet instead.

Configs written before tokens existed stop working after the upgrade: the server answers 401 until the token is added. Copy a fresh config from settings and paste it over the old entry.

The app has to be running while the agent works — the tools talk to the live window, not to a database file on disk.

The 32 tools#

Workspaces (3). list_workspaces, get_workspace, create_workspace. Listing reports the active, remote and sync state of each workspace; creation always makes a local one.

Collections (6). list_collections, get_collection, create_collection, update_collection, move_collection, delete_collection. Nesting goes through parent_id, moves are checked for cycles, deletes are soft and cascade to descendants. Updates use optimistic locking, so pass the current version.

Requests (7). list_requests, get_request, create_request, update_request, move_request, send_request, delete_request. Create and update accept HTTP, gRPC and GraphQL along with headers, auth and scripts. send_request really hits your API: it resolves environment variables, runs your scripts, returns status, headers and body, and appends an entry to history.

Environments (4). list_environments, get_environment, create_environment, delete_environment.

Variables (3). list_variables, create_variable, delete_variable. Writing values is unrestricted; reading them is not — see below.

Sync (9). sync_status, sync_push, sync_pull, sync_queue_list, sync_queue_clear, sync_resync, sync_pause, sync_resume, sync_disconnect_stream. This is the debugging set for Tetiva Cloud: inspect engine state and the outbox, force a push or a pull, pause and resume a workspace, or drop the event stream once to exercise the backoff and reconnect path.

Security#

The token

The server requires a token. It is generated on first launch, stored in the app database alongside the rest of the MCP settings, and accepted two ways — Authorization: Bearer <token> or ?token=<token> — because not every client can express both. Anything else gets a 401 whose body says where the working config lives. Both the SSE endpoint and the message endpoint are checked, so a leaked session id on its own buys nothing.

Regenerate in settings rotates the token on the running server immediately; every agent config still carrying the old value has to be updated. Require token turns the check off. That is an escape hatch for a client that can send neither form, and a deliberate one: with it off, any process on the machine — a browser tab reaching 127.0.0.1 included — can read every collection and variable and send requests as you.

The default address is loopback, and a host-less :9300 is normalized to 127.0.0.1:9300 at startup, including for configs saved earlier. Set a network-facing address deliberately and the app keeps it, but writes a warning to the log and highlights the field in settings.

What the token does not protect against: anyone who can already read ~/.tetiva/data.db. That file holds the token itself along with everything else. Encrypting the local database is a separate matter.

What tools redact

  • auth_data on requests and collections — always [redacted], leaving the auth type visible.
  • Values of variables flagged as secret — withheld from list_variables, get_environment and the create-variable response.
  • Values of credential headers, in stored requests and in send_request responses: authorization, proxy-authorization, cookie, set-cookie, x-api-key, api-key, x-auth-token, x-access-token, x-csrf-token, x-session-token.
  • gRPC metadata under those same names — for a gRPC request that is where the token lives instead of a header.
  • Credential query parameters in a request URL: token, access_token, refresh_token, api_key, apikey, key, secret, password, sig, signature.

A value that is nothing but a {{variable}} placeholder is left alone: it names a variable rather than being the secret, and the agent needs to see which one is in play. A value that merely embeds one — session=abc; theme={{ui}} — is redacted, because the literal half of it is still a secret.

Deliberately not redacted: request and response bodies — without them send_request is useless for debugging, so a token returned in a login response comes through in full — pre- and post-request scripts, and variables not flagged as secret.

Redaction does not cost you data. update_request and update_collection apply just the arguments you pass, so a field the agent leaves out keeps its stored value. Some fields cannot be left out — changing one header means resending the whole array — so every [redacted] that comes back on a write is matched against what is stored under the same name and swapped for the real value before anything is saved. A mask with nothing behind it is refused rather than written: create_request and create_collection reject [redacted] outright, and on an update a mask under a name that has no stored counterpart — a header the agent has just added, say — comes back as an error asking for the real value. Sync is a separate story, described in full on the Sync page.

Data directory#

The tools read and write the same database as the window: ~/.tetiva/data.db. The directory is overridden by TETIVA_DATA_DIR (the older GOPHERCOURIER_DATA_DIR still works as a fallback). That is the clean way to give an agent a second Tetiva instance with its own database and its own MCP port, well away from your real collections. See Settings for the full data layout.

updated