Guides
Projects and keys
Create projects and keys, understand key kinds, read-only keys and tool allow-lists, handle expiry, revoke and rotate keys without downtime, and set project settings.
A project is one MCP endpoint with its own keys, settings and agents. A key authenticates an agent or a client to one project. This page covers creating them, what each kind of key can do, how to rotate a key without downtime, and the practices that keep a leaked key small.
Projects
A project has an id, a name, a set of keys, settings, and (while one is connected) agents and the tools they register. It belongs to exactly one account. Use one project per environment or per service you want clients to see as a separate server, for example orders-prod and orders-staging.
Create a project
Press New project (top bar, or the Projects page), enter a Name of 1 to 60 characters, and press Create project. You land on the project page and see Copy your key now with the project's first key: a full key labelled Default.
The Free plan allows up to 5 projects by default. Past the limit, the dialog returns The Free plan is limited to 5 projects.
Rename and delete
- Rename: on the project page open Project settings, change Name and press Save settings. The id and the endpoint do not change, so nothing needs redeploying. Clients see the project id as the server name, not the display name.
- Delete: press the red Delete project button on the project page and confirm. Its keys, call logs and usage history are deleted and cannot be recovered. Connected agents are disconnected at once, calls they were running fail with
Project deleted., and its keys stop working (401Invalid API key.).
The project id and the endpoint
In the API keys panel of the project page, two copy buttons give you:
| Looks like | Use | |
|---|---|---|
| Project ID | 493988ba-69ea-4101-99d4-3c2a5cbab5be | The last segment of the endpoint URL |
| MCP endpoint | https://api.spacefix.io/mcp/<project id> | What you give an MCP client, with a client key |
The id is not a secret and the endpoint alone grants nothing. A key only works for its own project: a valid key for project A used on project B's endpoint is refused with 403 and Forbidden - agent identity mismatch.
Your service needs only the key and the gateway address, as SPACEFIX_API_KEY and SPACEFIX_SERVICE_URL. The project id is not configured in the agent; the key identifies the project.
Key types
| Kind | Dashboard label | Use it for | Allow-list |
|---|---|---|---|
agent | Agent | The SDK in your service: it registers tools and answers calls. It cannot call tools | No |
client | Client | An MCP client: it calls tools. It cannot register tools or connect an agent | Yes |
full | Full | Both: your service and AI apps. Every new project's Default key is one | Yes |
Each kind opens one door, or both:
| Door | Who uses it | Accepts |
|---|---|---|
| The agent connection (what the SDK calls) | Your service | agent, full |
The MCP endpoint (/mcp/<project id>) | MCP clients | client, full |
A genuine key on the wrong door is refused with 403 and a message that says which kind it needs, for example This is an agent key. MCP clients connect with a client key. That refusal does not count toward the failed-login budget.
Create a key
- On the project page, in API keys, press Create key. The dialog is titled Create an API key.
- Fill in:
| Field | Meaning |
|---|---|
| Label | 1 to 60 characters, for example production or claude-desktop. It is shown on the Agents page, in Logs and in Traces, so make it recognisable |
| Type | Full: for your service and AI apps (the default), Agent: for your service only or Client: for an AI app only. The line under the field says what the chosen type does: a full key works on both sides; an agent key goes in the service that runs your tools and lets it connect and offer them, but cannot call them; a client key goes in an AI app such as Claude, Cursor or VS Code and lets it see and call your tools (optionally limited to some tools or to reading), but cannot offer tools |
| Expires | Never, In 30 days, In 90 days or In a year |
| Access | Read and write: every tool (the default) or Read only: tools that only read. Hidden for the Agent type. See Read-only keys |
| Allowed tools (optional) | Comma-separated names; * matches any text. Empty allows every tool. Hidden for the Agent type |
- Press Create key. Copy your key now shows the secret and the two lines for your service.
A project holds up to 10 active keys on the Free plan by default (revoked and expired keys do not count). Past the limit, Create key returns The Free plan is limited to 10 active keys per project. Keys are created on a project's page; the API keys page lists them across projects but creates none.
The secret is shown once
A secret looks like sf_live_ followed by 22 random letters and digits. The recognisable prefix lets secret scanners find a leaked key. We store only a hash of it, so we cannot show it again: a lost key is replaced, never recovered.
Afterwards you can see a 12-character prefix (sf_live_USuX…) to recognise a key by, its label, kind, last-used date and expiry. Last used updates at most once a minute; Never means no request has authenticated with it, and such keys are worth deleting.
If you close the browser tab before copying a new project's first key, it is gone; create another key from the API keys panel.
Tool allow-lists
A client or full key can be limited to some tools, so a leaked or over-curious client cannot reach the rest.
- Patterns are tool names with
*as a wildcard for any run of characters:get_*matchesget_orderandget_all_orders;*_ordermatchesget_orderandcreate_order. Nothing else is special. Matching is case-sensitive and must match the whole name. - Up to 50 patterns; each uses letters, digits,
_,-and*. An allow-list on an agent key is refused:A tool allow-list applies to client and full keys. - A tool outside the list is absent from
tools/listfor that key, and calling it fails as if it did not exist:Tool <name> not found(JSON-RPC-32602). - The allow-list applies to tools only. It does not filter resources or prompts: a key with an allow-list still sees every resource and prompt the project offers.
- You cannot edit a key's allow-list or expiry after it is created. Create a replacement key and revoke the old one.
Because your handlers cannot tell who called them, the key is the only place to draw the line between what one client may do and what another may.
Read-only keys
A client or full key can be limited to tools that only read: pick Read only: tools that only read under Access when you create it. The keys table shows it with a Read only pill.
- A tool reads when its agent sets
readOnlyHint: trueon it (see Building agents), or when you mark it Read under Tools. A tool with neither counts as a write, so it is hidden from a read-only key. This is on purpose: a missing label hides a tool, it never lets a write through. - A tool that does not read is absent from
tools/listfor that key, and calling it fails as if it did not exist:Tool <name> not found(JSON-RPC-32602). - Resources and prompts always count as reads, so a read-only key still sees all of them.
- With an allow-list as well, a tool must pass both.
- Read-only on an agent key is refused:
Read-only access applies to client and full keys. - Keys created without a choice, including every key made before this setting existed, read and write. You cannot change a key's access after it is created; create a replacement and revoke the old one.
Mark a tool yourself. On the project page, press Edit on a tool and set Reads or writes to Follow the agent, Read: read-only clients may call it or Write: hidden from read-only clients. The hint under it says what the agent declares. A tool you set shows a Treated as read or Treated as write pill.
To limit every client of a project at once, use Client access in Project settings. Check connection says how many tools a read-only client sees, and warns when it is none.
Expiry
An expired key stops authenticating and disappears from the lists. We email you 14 days and 3 days before a key expires, naming the key and the project (turn it off with Key expiry in Settings, Notifications). The API keys page shows keys expiring within 14 days in amber and within 3 days in red.
An expired key disconnects its agent. If an agent is connected with a key that expires, its connection is closed shortly afterwards (within about half a minute) and calls it was running fail. The SDK then tries to reconnect with the same key, is refused with 401, and keeps retrying; in the Node.js SDK the log reads API key was rejected (401). Check SPACEFIX_API_KEY. So rotate before the expiry (below) and restart the agent with the new key.
Revoking a key
Press the red Revoke on a key row (or Manage, then Revoke, on the API keys page) and confirm.
- The key stops working on the next request.
- An agent connected with it is disconnected, and its running calls fail with
Key revoked. - It is recorded as
API key revokedin Activity, and a webhook is sent if you set one up. - It cannot be undone, and the key leaves the list.
Rotating a key without downtime
Creating a key does not revoke the old one, so both work in between. There is no Rotate button: you rotate by creating, deploying and revoking.
- Create a new key of the same kind with a new label, for example
production-2026-11. - Deploy it: set
SPACEFIX_API_KEYin the deployment and restart. The agent reconnects with the new key. - Check that the new key shows a Last used date, that the Agents page shows the agent with the new key's label, and that the old key's Last used has stopped moving.
- Revoke the old key.
If you run more than one replica and restart them in turn, there is no gap: the others keep serving while each one reconnects. The same sequence works for a client key: create a new one, update the client's configuration, then revoke the old one.
Project settings
On the project page, Project settings applies to this project only:
| Setting | What it does | Valid values | Default |
|---|---|---|---|
| Name | The project's display name | 1 to 60 characters | What you entered |
| Client access | The most any MCP client of this project may do, whatever its key or token allows | Read and write, Read only | Read and write |
| Call timeout (seconds) | How long the gateway waits for one of your tools to answer before giving up | A whole number from 1 to 30 | Blank: 30 seconds |
| Allowed client addresses | Restricts which source addresses MCP clients may call from | One IP address or CIDR range per line, IPv4 or IPv6, up to 20 | Empty: any address |
Press Save settings (it stays greyed out until you change something). Changes apply to the next request; nothing to restart or redeploy.
Call timeout. When a tool does not answer in time the client gets an error result with Request for tool "slow" timed out after 2000ms., and the call is logged as Timed out. The same timeout applies to resource reads and prompt renders. You can lower it, not raise it above 30 seconds.
Client access. Read only limits every client key, full key and OAuth token on this project to tools that read, exactly like a read-only key. Your agents are not affected, and neither are Try a tool and the Playground, which run as you. The Tools panel shows clients: read only while it is on.
Allowed client addresses. A client calling from an address that is not on the list is refused with HTTP 403 and JSON-RPC error -32004: This address is not on the project's client allow-list. Only MCP clients are limited: your agents connect from wherever your service runs and are never held to this list. The address checked is the one the gateway sees, so clients behind a corporate proxy or NAT present the proxy's address. If you lock yourself out, change the list from the dashboard, which the list does not affect. Check connection warns when a list is set.
Best practice
- One key per deployment, one key per client. If a laptop is lost, you revoke one client key and everything else carries on.
- Use the narrowest kind. Agent keys for services, Client keys for clients. Keep Full keys for experiments.
- Replace the Default key. Once you have dedicated keys, revoke Default: a full key can both register tools and call them, which is more power than any one party needs.
- Label for the future reader.
claude-code-adais more useful thankey2in Agents, Logs and Traces. - Scope client keys. Give a client only the tools it needs, such as
get_*, so a leaked key cannot call a destructive tool. A client that only needs to look things up gets a Read only key. - Set an expiry on keys you hand to people or short-lived environments, and keep the reminder email on.
- Keep keys in a secrets manager, not in the repository or in a client config you commit. An agent key lets its holder register tools and receive every call's arguments; a client key lets its holder call your tools.
- Set
SPACEFIX_SERVICE_URLand the key per environment, so a staging build cannot register against production. - Watch Activity. Key creation and revocation are recorded with the time and address.
Behaviour worth knowing
- Failed-key budget. Repeated rejected keys from one address are limited (30 a minute by default) and then get
429Too many failed authentication attempts.withRetry-After. A valid key is never limited by this, so one stale agent cannot lock out the rest of an office. - Request rates are per project, not per key. See Plans and limits.
- Changes apply to the next request. Revoking a key, editing a tool and saving project settings take effect on the next request that reaches the gateway.
Next steps
- Connecting clients: put a client key into Claude Code, Cursor and others.
- Running replicas: restart replicas in turn when you rotate an agent key.
- Security guide: how keys are stored and what to do after a leak.