Starko MCP Server: Your Workspace in Claude, Cursor, VS Code

Starko MCP Server: Your Workspace in Claude, Cursor, VS Code

Starko now speaks the Model Context Protocol. Any MCP host, Claude.ai, Claude Desktop, Claude Code, Cursor or VS Code, can connect to a Starko workspace at https://v2.starko.one/api/mcp and use the same tools the ⌘L chat and Starko in Slack use: tickets, conversations, CRM, knowledge base, reporting, workflows and Starko AI runs. You sign in with your own Starko account, pick one workspace, and every action that needs a person's approval still asks for it. There are no API keys. It shipped between 31 October and 1 November 2026, and the first real connection from the Claude app went through on 1 November.

The consent screen and the first tool call from Claude Code

This post was written in a Claude Code session that had the Starko connector attached. The project list it quotes below came back over MCP.

MCP removes the switch between the dashboard and the editor

The factory loop we describe in runs inside Starko: feedback becomes tickets, tickets become recommendations, accepted recommendations become Starko AI runs. But the people who decide what gets built do not live in Starko all day. They live in an editor, in a terminal, in a chat with a model, often the same on their codebase. Every time one of them wanted a ticket's details, a customer's history or a run started, they switched to the dashboard, found it, and switched back.

MCP removes the switch. The tool the ⌘L chat calls to search tickets is the same tool Claude Code calls now. The person stays where they were, and Starko stays the system of record.

We decided on one constraint before writing a line: authentication is OAuth 2.1 only. A personal access token is a password that never expires and that nobody rotates. A token minted through a consent screen is bound to one person, one workspace and one client, and it dies when that person leaves the workspace.

Connecting takes three steps

  1. A workspace owner enables MCP access under Settings → Connections → Starko MCP server. The switch is owner only, and off by default.
  2. Add the endpoint to your host. In Claude.ai, Cursor or VS Code it is a custom connector with the URL. In Claude Code it is one line:

    bash
    claude mcp add --transport http starko https://v2.starko.one/api/mcp
  3. Click Connect. Starko opens, you sign in with your own account, and you pick the one workspace this connection may act in. Approve, and the host has its token.

The public documentation at renders the tool list straight from the server's registry, so it cannot drift from what the server offers.

One tool registry feeds the chat, Slack and MCP

The first pull request in the series was not the MCP server. It was a refactor. Before it, the ⌘L chat assembled about forty hand-written tool groups, Starko in Slack repeated seventeen of those calls, and the approval policy for each tool was encoded four times: in the tool module, in the chat's confirmation list, in Slack's gated labels and in the approval card text.

Now each tool is defined once, in one registry entry: name, title, description, input schema, the function that runs it, a policy that says whether it needs approval and whether it is read only, the surfaces it appears on, and where it depends on the person or the workspace, an availability check. The chat route, the Slack agent and the MCP endpoint all assemble their tool sets from that registry. The chat's confirmation list and labels are a generated projection of it.

A test proves the refactor changed nothing the models could see: the chat and Slack tool lists, their order, their gating, their descriptions and their JSON schemas reproduce the pre-refactor fixture byte for byte. Where the two surfaces genuinely differed, the difference is now written down in the registry instead of hidden in two files. Creating a workflow, for example, is inline in the chat, where saving it inactive is the human step, and an approval card in Slack, where approving activates it.

MCP is simply a third surface. Tools that only make sense in a chat, navigation, asking the user a question, follow-ups, attachments and exports, are not on it.

A connection gets 75 tools, filtered by role and workspace

On the day of writing, the live documentation lists 75 tools over MCP. 45 of them are read only and 30 write. 38 need a person's confirmation before they run.

GroupExamples
Tickets and projectssearchTickets, getTicketDetails, createTicket, updateTicket, addTicketComment, createProject
Customer conversationssearchThreads, getThreadDetails, replyToThread, threadAction
CRMsearchCompanies, searchDeals, getDealDetails, crmWrite
Knowledge basesearchArticles, getArticleContent, createKbArticle, updateKbArticle
ReportinggetReportingAnalytics, queryAnalytics, getTeamWorkload, getSlaStatus
Ticket workflowslistTicketWorkflows, createTicketWorkflow, runTicketWorkflow
Starko AIassignStarkoAi, startStarkoSession, steerStarkoSession, mergeStarkoPullRequest

What a given connection sees depends on the person's role and the workspace's configuration. The ERP tools one customer uses, for example, appear only in a workspace that configured them and only for people in its sales team. That is the same availability check the chat uses, applied at tools/list time.

Here is the first read this session made through the connector, trimmed to our own projects, so you can see the shape of a result:

json
{ "ok": true, "data": [  { "name": "Starko - Main development", "status": "backlog", "ticketTotal": 313, "ticketClosed": 97, "url": "/dashboard/projects/8430fd7f-..." },  { "name": "Starko Widget v2", "status": "backlog", "ticketTotal": 0, "ticketClosed": 0, "url": "/dashboard/projects/5648fb8c-..." }] }

Every tool carries MCP annotations from its policy: readOnlyHint, destructiveHint and idempotentHint. Tools that need confirmation are listed as destructive, so hosts that honour annotations ask before calling them even before Starko does.

Writes never run on the first call

The chat draws an approval card for a gated tool and runs it when you click. MCP has no card to draw, and in a stateless deployment the server cannot ask the client a question and wait for the answer: the client's reply arrives as a new HTTP request on a fresh transport. We found that out while building the elicitation path, which the protocol offers for exactly this purpose, and kept it behind a capability check.

So gated tools over MCP work like this. The first call does not execute. It returns approval_required with a plain summary of what would happen and a one-time confirmation_token. The host shows the summary. Once the person agrees, the host repeats the call with the same arguments and _confirm set to the token. The token is an HMAC over the person, the grant, the tool and the canonical input, valid for ten minutes, and it is claimed once in Redis, so a replay is refused even across serverless instances. Change an argument between the two calls and the token no longer matches.

Two more guards sit on the write path. Tools that in the chat default to "the workflow you are viewing" have no page to look at over MCP, so workflowId becomes required and the "defaults to the one you are viewing" wording is removed, done once in the registry. And each person is limited to 120 calls a minute.

OAuth 2.1 with Starko as the authorization server

Starko did not have an authorization server before this. It has one now, built against the MCP authorization specification for HTTP transports and nothing beyond it.

  • Discovery. /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server tell a host where to register, authorize and exchange tokens. An unauthenticated call to the endpoint answers 401 with the WWW-Authenticate challenge that points at them, so a host finds its way with no configuration.
  • Client registration. Hosts identify themselves with a Client ID Metadata Document, a URL they serve that describes them, fetched through the same SSRF guard the rest of Starko uses. Older hosts can use dynamic registration. Public clients only, with PKCE S256.
  • Consent. The authorization page lives inside the signed-in app, in the onboarding's design language. It shows the client, where the browser returns afterwards, a warning when that is localhost, the workspaces you belong to with the role you would act as, and the two scopes: read your workspace, and act in your workspace as you. A request that cannot be verified renders an error on that page and never redirects.
  • Tokens. Opaque, hashed at rest, one hour for access and thirty days for a rotating refresh token, bound to the MCP endpoint as audience. A token maps to a person and a workspace. The person's role is read fresh on every call, so a demotion takes effect immediately and a removed member gets 401 and their tokens revoked.
  • Hardening. Authorization codes are single use with a sixty second life. A replayed code revokes the tokens it produced. Three wrong verifiers burn a code. A reused refresh token revokes the whole grant. Registration, token and revocation endpoints are rate limited. Redirect URIs must be https or loopback and match exactly.

The whole server, tokens included, is 47 tests on top of an in-memory store with the same contract as the database one, plus end-to-end tests that drive the MCP route with the protocol SDK's own client: discovery challenge, bad token, switch off, list tools, a read call, scope filtering, the full gated flow and the elicitation fallback.

The first Claude connection failed on a grant type

Connecting from the Claude app ended on the consent screen with "Unknown client. The app must register before asking for access." Claude's metadata document declares three grant types, including one Starko does not offer, and our validator refused the whole document for it. The fix, merged the same night, ignores grant types the server does not support as long as the authorization code grant is there. The client simply cannot use the others here.

Two smaller things followed from the same session. Hosts showed the bare Starko logo edge to edge next to the connector, so the server now advertises a padded icon through the protocol's icon field. And the connection got its own line-art glyph on the consent screen, three hosts plugged into the Starko node, in the same language as the onboarding.

The last pull request prepared the connector for the Claude directory. 39 of the 74 tool descriptions at the time carried chat wording such as "pauses for approval in chat", and 29 named other tools, which the directory policy forbids. Every tool now has a separate description for the MCP surface that says what it does, what it takes and what it returns, and a test rejects behaviour wording and other tools' names on that surface so it cannot regress.

Metering and elicitation are not done

Metering. The chat meters model tokens per run, and over MCP the host's model does the thinking, so there is nothing equivalent to meter. Only the rate limit exists today, and what an MCP call should cost is a product decision we have not made. Elicitation, the protocol's native way to ask the person a question mid-call, needs a session-bound transport with shared state before it can work on serverless; the confirmation token is what every host hits today. And the newest protocol methods are not in the SDK version we run, so the endpoint negotiates down to what hosts speak.

Frequently Asked Questions

Does an MCP connection bypass permissions?

No. The token maps to one person and one workspace, and every tool call runs as that person with the role they have at that moment. The tools' own workspace and capability checks are the same code the dashboard runs. A connection can never do more than the person could do in Starko.

Can I use an API key instead of OAuth?

No. The server accepts only tokens issued through the consent screen. That is deliberate: a token is tied to a person, a workspace and a client, it expires, and it dies when the person leaves the workspace or the owner switches MCP access off.

What happens when a tool needs approval?

The first call returns a summary and a one-time confirmation token instead of running. Your host shows the summary. When you agree, it repeats the call with the token and the tool runs once. Tokens last ten minutes and cannot be reused or applied to different arguments.

Which hosts work today?

Any host that implements the MCP authorization flow over Streamable HTTP. We have connected Claude Code and the Claude app ourselves. Cursor and VS Code take the same custom connector URL. If your host shows "Unknown client", tell us which one and we will look at its metadata document.

Stefan Vukmanovic

Stefan Vukmanovic

Founder, Starko

Stefan Vukmanovic is the founder of Starko, the software factory that turns customer feedback into merged pull requests. He built the support side first, the AI helpdesk, ticketing and knowledge base, and now builds the factory on top of it: feedback becomes recommendations, coding agents build the accepted ones, and the team pays only for what it merges. He writes about running that loop in production.

Published

November 1, 2026

Category

Factory