How to connect an MCP client
Vantik speaks the Model Context Protocol. An
LLM agent therefore creates, picks up, notes, and closes an issue, and it
searches the past work. Claude Code, Cursor, and any other client with MCP can
do this, and you connect no REST endpoint by hand. The server gives a set of
tools with the shape of a task. The difficult parts happen on the server: it
finds the id of ENG-42, it converts the markdown, and it posts a resolution
before it closes an issue.
The endpoint is:
POST /v1/mcp
It is a stateless MCP server with the
Streamable HTTP
transport. It uses the same
authentication with a personal access token as the other parts
of the API. The token travels in the Authorization header.
How to get a token
Make a token in Vantik → Settings → Agents. An agent account is a separate
identity in the workspace. The workspace therefore records each issue and each
note against the agent, and not against you. When you make the account, the page
shows the token one time. It also shows a .mcp.json file and a claude mcp add
command that you can copy. Copy them at that moment, because you cannot read the
token again.
Only an administrator can make an agent. If you do not see Settings → Agents, ask an administrator of the workspace to make the agent and to give you its configuration.
How to connect Claude Code
Add the server to the .mcp.json file of a project. Use your own host and your
own token:
{
"mcpServers": {
"vantik": {
"type": "http",
"url": "https://your-vantik-host/api/v1/mcp",
"headers": { "Authorization": "Bearer tg_pat_…" }
}
}
}
You can also register the server from the command line:
claude mcp add --transport http vantik https://your-vantik-host/api/v1/mcp \
--header "Authorization: Bearer tg_pat_…"
Do not commit a live token. The .mcp.json file of a project usually goes into
version control, and this file holds a token that reads and writes the
workspace. Keep the file out of version control, or register the server for your
user only. claude mcp add writes to ~/.claude.json, which is not in the
repository. If a commit does hold a token, revoke that agent in Settings →
Agents and make a new one.
How to connect another client
Any MCP client with the Streamable HTTP transport connects in the same way.
Point it at https://your-vantik-host/api/v1/mcp, and send the token in an
Authorization: Bearer header. The /api prefix is the webapp proxy in front of
the server. If you call the server directly, remove that prefix and use
/v1/mcp.
Name the session that reads the knowledge
Vantik records each knowledge entry that it serves, so that it can learn which entries help the work. The record holds the token, and it holds the session of the agent when the agent names one. The MCP endpoint keeps no session, so the agent names its session in one of two ways:
- Pass
sessiontorecall_knowledgeor toload_context. This is the same argument thatremembertakes. - Send an
X-Vantik-Sessionheader with each request. Use this for a client that serves one session and can set a header for it.
Either way, a session is printable ASCII characters with no spaces, at most 200 of them. Vantik ignores any other value and still serves the knowledge.
If the agent names no session, the record holds only the token.
The tools
| Tool | What it does |
|---|---|
list_tasks | Lists the tasks as small rows. You can filter by team, assignee, state, labels, priority, and project. |
get_task | Gives everything about one task in one call: the description, the notes, the history, the sub-tasks, and the relations. |
search_tasks | Searches the titles, the descriptions, and the notes. Set stateCategory: ["COMPLETED"] to find an earlier fix with its resolution. |
find_similar_tasks | Gives the earlier tasks that are similar to one task, and the resolution of each. |
create_task | Files an issue. It holds an issue to a minimum: a real description, and acceptance criteria for a top-level issue. |
update_task | Changes the title, the description, the state, the labels, the priority, the assignee, or the project of a task. |
list_projects | Gives the projects of the workspace. A project is an objective, and the issues group under it. |
create_project | Opens a project for an objective that truly needs several issues. |
pick_up_task | Takes ownership of a task. It assigns the task and moves it to the in-progress state. |
add_note | Puts a markdown note on a task, and the search finds that note. |
close_task | Closes a task. It first records the resolution as a note, so the search finds the fix later. |
Each tool uses the REST API from How to work with agents. Read that page for the endpoints below the tools, or for a client that you build directly against the API.
Rate limits
The endpoint has a rate limit for each token. An agent in a loop therefore
limits only itself. Above the limit you get HTTP 429, a Retry-After header,
and a JSON-RPC error body. The body holds the same wait time in
data.retryAfter.
| Variable | Default | What it sets |
|---|---|---|
MCP_RATE_LIMIT | 120 | The number of requests that one token can make in one window. 0 stops the limit. |
MCP_RATE_LIMIT_WINDOW_MS | 60000 | The length of the window, in milliseconds. |
The counters live in the server process. Across several replicas, the real limit
is therefore the limit multiplied by the number of replicas. That is enough to
stop a loop that runs away. For a true quota, put your own limiter in front of
the server and set MCP_RATE_LIMIT=0.
Optional: a house style, as agent skills
The configuration above is all that an agent needs to read and to file an issue. But an agent alone files many small issues. It opens a new issue where a note on an issue that exists is enough, and it divides one piece of work into six issues.
Vantik has three short guides that correct this. Each guide is an agent skill:
- working-vantik-issues says to file fewer and larger issues. It says to group the issues of one objective under a project. It says to add a note to an issue that exists, and not to open a near-duplicate. It also says to write the definition of "done" before you file the issue.
- working-vantik-knowledge says to load the context of the knowledge bank before the work starts, and to record one fact at a time.
- delegating-vantik-work says when an issue is ready to give to the agent
of Vantik with
delegate_task, and how to read the runs thatlist_agent_runsgives.
The issues guide sits above the create_task tool, and that tool already
refuses an issue with no description or no acceptance criteria. The tool sets
the minimum. The guide gives the judgement about what to file.
Each Vantik server publishes its guides at /.well-known/agent-skills/, in the
format of the Agent Skills discovery index. Install them with the
skills CLI. Use your own host:
DISABLE_TELEMETRY=1 npx skills add https://your-vantik-host
The command asks which guides to install, for which agents, and whether to
install them for this project or for all your projects. It knows where each
agent keeps its skills: Claude Code, Codex, Cursor, and many more. To name the
agent, add --agent claude-code, --agent codex, or --agent cursor. Each tab
in Settings → Agents shows the command with its agent.
After you upgrade Vantik, run npx skills update. The guides name the tools of
your server, so the copy from your server is the copy that matches it.
DISABLE_TELEMETRY=1 stops the skills CLI from sending a report of the install.
For a source that is not a public GitHub repository, that report holds the name
of your host.
You can also install the guides from the Vantik repository on GitHub, for example to read them before you have a server:
npx skills add cmunte132/vantik
That copy follows main, which can be ahead of the Vantik version that you run.
Always in the context
A skill loads on demand. Sometimes an agent still works quietly, and reports only at the end, because no part of the task looked like issue work until the task was complete. For that agent, add the issues guide to a file that the agent always reads:
# Claude Code
curl -fsSL https://your-vantik-host/api/v1/agent-skill/CLAUDE.md >> CLAUDE.md
# Codex, Cursor, and any other tool
curl -fsSL https://your-vantik-host/api/v1/agent-skill/AGENTS.md >> AGENTS.md
The server makes both files from one source text, so there is one source of
truth and not copies that become different. The originals are in
skills/ at the root of
the repository.
Always on: the server instructions
When a client connects, the MCP server sends a short form of the rules in the
instructions field of MCP. Claude Code and Codex keep that text in the context
for the whole session. An agent there therefore gets the rules even if it never
loads a skill: pick up the issue before the first edit, tick each criterion when
it is met, and close the issue with a resolution. You configure nothing for
this.
Optional: hooks that keep the tracker current
A skill is advice, and the agent decides when to read it. Hooks make two parts of the guidance certain:
- At the start of a session, the agent gets a list of the issues that it has in progress, with how much of each Definition of Done is met.
- Before the agent stops, Vantik examines each of those issues. If an issue has had no update from the agent for 20 minutes of this session, Vantik holds the agent once and asks it to record where the issue stands. A note, a ticked criterion, or a change to the issue counts as an update. If the session did not touch the issue, the agent can say so in one line and stop.
Vantik asks once for each quiet period. After the agent writes to the issue, a
new quiet period of 20 minutes can cause one more request. The rules are on the
server, so the hooks only relay the answer. The hooks write nothing to the
tracker. If Vantik does not answer, the hook prints {}, and the agent
continues as if there were no hooks.
Settings → Agents shows the hooks for each agent, with your host already in them.
Claude Code and Codex
Both agents can call a tool on an MCP server from a hook. The hooks call
hook_prompt_submit and hook_stop on the vantik server that you configured
above, so they use its connection and its token, and the file holds no secret.
You can commit it for your team. Add this to .claude/settings.json, or save it
as .codex/hooks.json and change claude-code to codex:
{
"hooks": {
"UserPromptSubmit": [
{ "hooks": [{ "type": "mcp_tool", "server": "vantik", "tool": "hook_prompt_submit",
"input": { "session_id": "${session_id}", "harness": "claude-code" } }] }
],
"Stop": [
{ "hooks": [{ "type": "mcp_tool", "server": "vantik", "tool": "hook_stop",
"input": { "session_id": "${session_id}", "harness": "claude-code" } }] }
]
}
}
The brief comes with the first prompt, and not at SessionStart. At launch,
neither agent has connected its MCP servers when SessionStart runs, so an MCP
hook on that event does not run. Codex asks you to trust a new hook before it
runs it.
Cursor
Cursor runs a hook as a shell command, so each hook is a curl command that
sends the input of the hook to Vantik. The command reads the token from
VANTIK_TOKEN, so the file holds no secret. Save this as .cursor/hooks.json,
and set VANTIK_TOKEN in the environment that starts Cursor:
{
"version": 1,
"hooks": {
"sessionStart": [{ "command": "curl -fsS -m 10 -X POST 'https://your-vantik-host/api/v1/agent-hooks/session-start?harness=cursor' -H \"Authorization: Bearer $VANTIK_TOKEN\" -H 'Content-Type: application/json' --data-binary @- || echo '{}'" }],
"stop": [{ "command": "curl -fsS -m 10 -X POST 'https://your-vantik-host/api/v1/agent-hooks/stop?harness=cursor' -H \"Authorization: Bearer $VANTIK_TOKEN\" -H 'Content-Type: application/json' --data-binary @- || echo '{}'" }]
}
}
Cursor cannot hold an agent at a stop. Vantik therefore sends the reminder back
as the next message, and Cursor submits it for the agent. These commands need a
shell with curl, as on macOS and Linux.
Any other agent
The endpoint behind the hooks accepts any agent that can run a command at the start of a session and before it stops:
POST /v1/agent-hooks/{session-start | prompt | stop}?harness={claude-code | codex | cursor}
Send the input of the hook as the body, with the token in the Authorization
header, as for the other endpoints. The harness parameter selects the format
of the answer. The endpoint needs only the read scope. The MCP hook tools call
this endpoint, and each call from them counts toward the MCP rate limit: one
request for each prompt, and one for each stop.