@roarkanalytics/sdk-mcp
Officialby roarkhq
README.md
# Roark TypeScript MCP Server
The official MCP server for the [Roark API](https://docs.roark.ai), published as
[`@roarkanalytics/sdk-mcp`](https://www.npmjs.com/package/@roarkanalytics/sdk-mcp).
Its code tool prompt and embedded docs index are generated from Roark's OpenAPI spec by
[app-agent-codegen](https://github.com/roarkhq/app-agent-codegen) and arrive here as pull
requests. Everything else, including the transports, auth, the code tool runtime, and the
named tools the remote OAuth server exposes (`src/directory-tools.ts`), is hand-maintained.
Four files carry generated regions: `src/methods.ts`, `src/code-tool.ts`,
`src/code-tool-worker.ts` and `src/local-docs-search.ts`.
## Installation
### Direct invocation
You can run the MCP Server directly via `npx`:
```sh
export ROARK_API_BEARER_TOKEN="My Bearer Token"
npx --yes --package @roarkanalytics/sdk-mcp@latest mcp-server
```
Code execution runs locally, so install [Deno](https://deno.com) first.
### Via MCP Client
There is a partial list of existing clients at [modelcontextprotocol.io](https://modelcontextprotocol.io/clients). If you already
have a client, consult their documentation to install the MCP server.
For clients with a configuration JSON, it might look something like this:
```json
{
"mcpServers": {
"roarkanalytics_sdk_api": {
"command": "npx",
"args": ["--yes", "--package", "@roarkanalytics/sdk-mcp", "mcp-server"],
"env": {
"ROARK_API_BEARER_TOKEN": "My Bearer Token"
}
}
}
}
```
### Cursor
If you use Cursor, you can install the MCP server by using the button below. You will need to set your environment variables
in Cursor's `mcp.json`, which can be found in Cursor Settings > Tools & MCP > New MCP Server.
[](https://cursor.com/en-US/install-mcp?name=%40roarkanalytics%2Fsdk-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkByb2Fya2FuYWx5dGljcy9zZGstbWNwIl0sImVudiI6eyJST0FSS19BUElfQkVBUkVSX1RPS0VOIjoiTXkgQmVhcmVyIFRva2VuIn19)
### VS Code
If you use MCP, you can install the MCP server by clicking the link below. You will need to set your environment variables
in VS Code's `mcp.json`, which can be found via Command Palette > MCP: Open User Configuration.
[Open VS Code](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22%40roarkanalytics%2Fsdk-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40roarkanalytics%2Fsdk-mcp%22%5D%2C%22env%22%3A%7B%22ROARK_API_BEARER_TOKEN%22%3A%22My%20Bearer%20Token%22%7D%7D)
### Claude Code
If you use Claude Code, you can install the MCP server by running the command below in your terminal. You will need to set your
environment variables in Claude Code's `.claude.json`, which can be found in your home directory.
```
claude mcp add roarkanalytics_sdk_mcp_api --env ROARK_API_BEARER_TOKEN="My Bearer Token" -- npx --yes --package @roarkanalytics/sdk-mcp mcp-server
```
### Claude.ai
Add Roark as a custom connector. This uses the hosted server, so there is nothing to install and no API key to paste.
1. Open Customize, then Connectors. On a Team or Enterprise plan, an Owner adds it under Organization settings, then Connectors.
2. Choose Add custom connector.
3. Enter `https://mcp.api.roark.ai/mcp` as the remote MCP server URL.
4. For authentication, choose to sign in. Leave the OAuth client on Claude's published identity, or on automatic registration. Do not add an API key under request headers.
5. Add the connector, then sign in with your Roark account in the browser when Claude asks.
The server reads and writes data in the signed-in account: agents, calls, transcripts, simulation results, metrics, personas, customer flows, and simulation runs. Roark is a voice and chat agent observability and simulation platform.
A project-pinned URL, `https://mcp.api.roark.ai/mcp/<projectId>`, is available when the connector should stay on one project. `https://mcp.api.roark.ai/mcp` reaches every project the account can use, and each tool takes a project id.
## Claude Code plugin and skills
The [`roark` plugin](./plugins/roark) bundles this MCP server with skills for
testing voice and chat AI agents. The MCP supplies access to the Roark API; the
skills provide the workflow for registering agents, authoring personas and
flows, building simulation run plans, configuring metrics, and reading results.
After adding the Roark marketplace once, install both together in Claude Code:
```
/plugin marketplace add roarkhq/mcp-roark-analytics
/plugin install roark@roark
```
The plugin connects to the remote Roark connector and signs you in through the
browser. No API key is set for the plugin. Its MCP server uses the `roark`
key, so its tools are exposed as `mcp__roark__*`. See the
[plugin README](./plugins/roark/README.md) for the complete setup and the
available skills.
### Skills in other agents
The skills are plain Agent Skills (`SKILL.md` + `references/`), so they are not
Claude-specific. Install them into any agent
with the `skills` CLI, which reads this repository directly:
```sh
npx skills add roarkhq/mcp-roark-analytics
```
Codex, Cursor, Gemini CLI and GitHub Copilot read the universal
`.agents/skills/` layout the CLI installs into; Claude Code gets
`.claude/skills/`. Repeat `-a` to pick targets
(`-a codex -a cursor`), and add `-g` for a user-level rather than project-level
install.
This installs the skills only. Configure the MCP server separately, as above, if
you also want the Roark API tools. See the
[plugin README](./plugins/roark/README.md) for which agents this works with and
why the skills must stay installed together.
## Code Mode
Local installs, and any server started without OAuth, use the "Code Mode" tool scheme. The
agent writes code against the TypeScript SDK, and that code runs in an isolated sandbox. That
surface exposes two tools:
- `search_docs`, which searches SDK documentation for methods, parameters, and response shapes.
- `execute`, which runs the code. The code cannot use the network or the filesystem except
through the SDK client. Whatever the code returns or prints comes back as the tool result.
The hosted server at `https://mcp.api.roark.ai/mcp` does not use Code Mode. With OAuth
enabled it exposes the named read and write tools described under Remote OAuth, not `execute`.
`--tool-surface=code` forces Code Mode on an OAuth server. `--tool-surface=directory` exposes
the named tools on a server that is not using OAuth.
## Running remotely
Launching the client with `--transport=http` launches the server as a remote server using Streamable HTTP transport. The `--port` setting can choose the port it will run on, and the `--socket` setting allows it to run on a Unix socket.
Authorization can be provided via the `Authorization` header using the Bearer scheme.
### Remote OAuth (account-based) mode
When the OAuth environment variables are set, the HTTP server runs as an MCP OAuth
**resource server** (RFC 9728): it serves Protected Resource Metadata pointing at Roark's
authorization server, and rejects requests without a bearer with `401` + `WWW-Authenticate`.
This is what lets users add the server to Claude, ChatGPT, Cursor, VS Code, etc. and sign in
with their Roark account instead of pasting an API key.
OAuth mode also switches the tool set. Instead of the `execute` code tool, which can both
read and write, the server exposes separate read tools and write tools (list agents, read
calls and transcripts, read simulation results and metrics, create a persona or customer
flow, run a simulation, and search docs). That is the surface served at
`https://mcp.api.roark.ai/mcp`. Pass `--tool-surface=code` to keep the code tool on an
OAuth server, or `--tool-surface=directory` to expose the named tools without OAuth. A
local stdio install stays on the code tool unless you pass `--tool-surface=directory`.
The access token the authorization server issues **is a Roark API key**: it is minted on the
consent page with the permissions the user picked (same picker as the CLI login), expires, and
is rotated by the client's refresh token. The server forwards it to the API as the SDK bearer
unchanged; the API validates it on every call.
| Variable | Meaning |
| ----------------------------- | ------------------------------------------------------------------------ |
| `MCP_OAUTH_ISSUER` | Authorization server issuer URL (enables OAuth mode) |
| `MCP_OAUTH_RESOURCE_BASE_URL` | Public base URL of this server, used to build metadata and resource URLs |
| `ROARK_BASE_URL` | API base URL the forwarded key is used against (SDK default) |
#### Connector URLs
There are two, and the difference is what the user consents to:
| URL | Consent grants | The credential |
| -------------------------------- | -------------------------------------- | ------------------------------------ |
| `https://<host>/mcp` | act as the person, in one organization | reaches every project they belong to |
| `https://<host>/mcp/<projectId>` | access to that one project | pinned to it |
`https://<host>/mcp` is the one to hand out. Added once, it follows the person across every
project they are a member of, so someone in five projects adds one connector rather than five.
Each URL publishes its own metadata (`/.well-known/oauth-protected-resource`, plus a copy under
the connector's path), and the `resource` identifier is the connector URL itself. Clients echo
that back to the authorization server per RFC 8707, which is how consent knows which of the two
grants is being asked for.
A pinned URL is not merely cosmetic: the project in the path becomes the SDK's `project`, so a
user credential used on `/mcp/<projectId>` acts on that project only.
#### Choosing a project on the unpinned connector
The unpinned connector deliberately sets no project, because there is no single right answer: the
credential reaches several. On the directory tool set, pass `project` to the tool. `list_projects`
returns the ids. On the code tool, name one per call:
```js
async function run(client) {
return await client.withOptions({ project: 'proj_123' }).call.list({ limit: 10 });
}
```
Calls that name no project fail with `400` and a message listing where to find the available ones
(`GET /v1/projects`). This is the `project` client option rather than a default header on purpose:
a default header would win over `withOptions`, and a pinned connector could then never reach
another project the credential legitimately covers.
When the OAuth variables are unset the server keeps the legacy header/Bearer behavior above, and
the stdio transport used by local installs is unaffected either way.
Additionally, authorization can be provided via the following headers:
| Header | Equivalent client option | Security scheme |
| -------------------------- | ------------------------ | --------------- |
| `x-roark-api-bearer-token` | `bearerToken` | Bearer |
A configuration JSON for this server might look like this, assuming the server is hosted at `http://localhost:3000`:
```json
{
"mcpServers": {
"roarkanalytics_sdk_api": {
"url": "http://localhost:3000",
"headers": {
"Authorization": "Bearer <auth value>"
}
}
}
}
```
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues