# Nemphi MCP server

> Connect Claude, ChatGPT, Cursor or any MCP client to your Nemphi workspace. Server URL, sign-in, code mode, approvals and troubleshooting.

Your AI assistant works in your workspace under the same rules, role permissions, approvals and ledger as the app.

## What it is

Nemphi's MCP server is a remote [Model Context Protocol](https://modelcontextprotocol.io) server. It lets an AI assistant (Claude, ChatGPT, Cursor or any MCP client) read and work in your Nemphi workspace.

It is not a side door. Every call runs through the same pipeline as the app: your role's permissions, the workspace's autonomy policies, approvals and the action ledger. What you cannot do in the app, the assistant cannot do on your behalf.

Server URL: `https://api.nemphi.com/mcp`. Streamable HTTP transport, stateless: each request is one independent POST.

## Connect in Claude and other clients

**Claude (web, desktop and mobile).** Open claude.ai, go to Settings › Connectors and look for Nemphi in the directory. If it is not listed yet, choose "Add custom connector" and paste `https://api.nemphi.com/mcp`. Claude sends you to sign in to Nemphi; pick the workspace and accept on the consent screen. Connectors are shared across the web, desktop and mobile apps.

**Claude Code.** One command:

```sh
claude mcp add --transport http nemphi https://api.nemphi.com/mcp
```

On first use, Claude Code opens the browser to sign in.

**ChatGPT, Cursor and others.** Any client that speaks Streamable HTTP and OAuth 2.1 with PKCE (S256) works. The server accepts dynamic client registration and Client ID Metadata Documents, so you do not need to ask us for a client id. Metadata is at `https://api.nemphi.com/.well-known/oauth-protected-resource`.

## Authentication

There are two ways to identify yourself.

**OAuth.** What connectors use. Two scopes: `tools:read` reaches read tools only; `tools` reaches read and write tools. Access tokens last 1 hour and refresh tokens 30 days; each refresh issues a new token and invalidates the old one.

**API key.** Create one in Nemphi under Developers › API keys and send it in the `Authorization: Bearer nk_…` header. The key inherits the role you assign it.

To remove access, disconnect the connector in the client or revoke the grant or the key from Nemphi. Either takes effect on the next call.

## Code mode

Nemphi has about 550 tools. Handing all of them to the model costs context and makes it pick worse, so the server exposes three tools and the assistant writes code that calls the rest.

| Tool | What it does | Arguments |
| --- | --- | --- |
| `search_tools` | Finds Nemphi tools by keyword. Read-only. | `{ "query": string, "module"?: string, "limit"?: number }`. `limit` is 1 to 20; default 8. |
| `run_read_code` | Runs a JavaScript snippet that may call read tools only. | `{ "code": string }` |
| `run_code` | Same, and may also call tools that change data. Every call still goes through the workspace's policies and approvals. | `{ "code": string }` |

`search_tools` returns, for each match, the tool's name, title, description, risk class and JSON input schema.

Inside the snippet:

- `nemphi.call(toolName, input)` calls a tool synchronously and returns its JSON result. On refusal it throws an `Error` whose `code` property says why: `approval_required`, `policy_denied`, `invalid_input`, among others.
- Whatever you write with `console.log(...)` comes back in `logs`.
- The value of the snippet's last expression comes back in `result`. A bare `return` at the top level does not work; end with the expression you want returned.

Limits per run: 30 seconds, 64 MB of memory, 50 tool calls and a result trimmed to 100 KB. No network, filesystem, timers or `import`.

Example, with `run_read_code`:

```js
const drafts = nemphi.call("invoices.list", { status: "draft" });

drafts.invoices.map((invoice) => ({
  number: invoice.number,
  total_cents: invoice.total_cents,
}));
```

**Full catalog.** A client that prefers one MCP tool per Nemphi tool can connect to `https://api.nemphi.com/mcp?tools=all`. Tool names are Nemphi's, for example `invoices.list`. Same pipeline; only the shape of the list changes.

## Approvals and safety

Read tools run right away.

Tools that post, pay, publish or send outside Nemphi, and tools that change what agents may do on their own, follow the workspace's policies. When a call needs a person's approval it returns `approval_required`. The assistant should tell its user; the person decides in Nemphi's inbox and the assistant retries or moves on. An assistant never approves on its own.

**Workspaces created by an agent.** When an agent created the workspace and its API key through self-serve signup, its user rarely has the app open. In those workspaces a call that needs approval is not lost: it is saved as a pending approval, and the response carries the approval id and a short summary for the agent to show its user. The agent relays the user's answer with two MCP tools: `approvals.pending` lists pending approvals and `approvals.decide` approves or denies one. In code mode they are `nemphi.call("approvals.pending", {})` and `nemphi.call("approvals.decide", { … })` inside `run_code`. Nemphi then runs the tool in the owner's name and the ledger marks the action "approved via the assistant". The owner can still decide or reverse it from Nemphi's inbox, and revoking the key stops the relaying.

Purchases that move money (buying a domain, changing the plan or overage) are not available over MCP. Do them in the app.

Every call lands in the action ledger with the actor "MCP client", the name of the person who authorized the connection, the tool and the result.

## What to ask your assistant

- "Which invoices are overdue this month, and who do we need to chase?"
- "Create a draft invoice for Comercial Los Andes for 12,480,000 COP with the items from quote 231."
- "Summarize this quarter's expenses by category and compare them with last quarter."
- "Which tasks in the Bodega Norte project have no owner?"
- "Log in the CRM that I spoke with Paula at Distribuciones Andina today and that I call back on Tuesday."

## Troubleshooting

**401 or "unauthorized".** The token expired or was revoked. Reconnect the connector, or create a new key if you were using one.

**`approval_required`.** The call is waiting for a person. Open Nemphi's inbox, decide, and ask the assistant to retry. In a workspace created by an agent, you can also answer the assistant and it relays your decision with `approvals.decide`.

**Tool missing or `policy_denied`.** Your role does not reach that tool, or the token was issued with `tools:read` and the tool writes. Ask an admin for the permission, or reconnect with the `tools` scope.

**`invalid_input`.** The assistant sent an argument the tool does not accept. The error message names it; `search_tools` returns the exact schema.

## Privacy and support

Nemphi receives only the tool calls the assistant makes: the tool's name and its arguments. It does not read your conversations or the rest of the assistant's context. What the assistant's provider does with the responses is governed by its own terms.

Data handling is described in the [privacy policy](https://www.nemphi.com/en/legal/privacy). For questions or problems, write to [hello@nemphi.com](mailto:hello@nemphi.com).
