workbench MCP server
Provides tools for interacting with the GitHub REST API, including listing, searching, and fetching issues, as well as creating issues and commenting on them.
Provides read-only access to SQLite databases with tools for listing tables, inspecting schemas, and running SELECT queries, as well as calendar event management backed by SQLite.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@workbench MCP servershow open issues in my GitHub repo"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP-powered agent
A tool server built from scratch on the Model Context Protocol, and a LangGraph agent that consumes it as an MCP client — plus Claude Desktop consuming the same server, unchanged.
That last part is the point. The server exposes GitHub, SQL and calendar tools over MCP and knows nothing about LangChain, LangGraph, or any agent framework. Two completely different clients drive it without a line of server code changing. That is what MCP is for.
MCP is the protocol Anthropic published and is standardising tool access around; OpenAI, Google DeepMind and Microsoft have since adopted it. It is, in effect, the USB-C port for LLM tooling.
┌──────────────────────────┐ ┌──────────────────────────┐
│ LangGraph agent │ │ Claude Desktop │
│ (hand-built StateGraph) │ │ (off-the-shelf client) │
└────────────┬─────────────┘ └────────────┬─────────────┘
│ │
│ MCP over stdio ─── or ─── streamable HTTP │
└───────────────────────┬───────────────────────┘
▼
┌─────────────────────────────────────┐
│ workbench MCP server (FastMCP) │
│ │
│ Tools 12 github / db / cal │
│ Resources 3 db://schema, … │
│ Prompts 3 triage_issues, … │
└─────────────────────────────────────┘
│ │ │
GitHub REST SQLite SQLite
(real API) (read-only) (calendar)Why MCP, and not just LangChain tools?
The fair question an interviewer will ask. Defining @tool functions inside the agent is less code.
What you give up:
LangChain tools in-process | Tools behind MCP | |
Reuse | Bound to your agent | Any MCP client — Claude Desktop, Cursor, your agent |
Language | Must be Python | Server can be any language |
Isolation | Shares your process, deps and crashes | Separate process, own dependency tree |
Deployment | Ships with the agent | Deployable and versioned independently |
Lock-in | Rewrite if you leave LangGraph | Swap the agent framework, keep the tools |
The cost is a serialisation boundary and a handshake. Worth it as soon as more than one thing needs the tools — which, in practice, is immediately.
Related MCP server: MCP Task Assistant
Quickstart
uv sync
cp .env.example .env # optional, see below
uv run mcp-agentuv sync pins Python 3.12 and installs everything. The SQLite database is created and seeded on
first run — there is no setup step.
Credentials are optional. With no .env at all:
the database and calendar tools are fully functional (they are local),
the GitHub tools return clearly-labelled fixtures (
"mode": "fixture") rather than pretending,only the chat loop needs a key, since it needs a model.
To chat you need one of:
LLM_PROVIDER=anthropic ANTHROPIC_API_KEY=sk-ant-...
LLM_PROVIDER=openai OPENAI_API_KEY=sk-...
LLM_PROVIDER=ollama # no key; needs Ollama running locallyFor live GitHub, add a fine-grained PAT with Issues: read+write and Metadata: read:
GITHUB_TOKEN=github_pat_...
GITHUB_DEFAULT_REPO=your-name/scratch-repo
create_issueandcomment_on_issuepost for real. The server refuses to guess a repository —GITHUB_DEFAULT_REPOmust be set explicitly, and the agent is instructed to confirm before writing.
Watch the protocol itself
Before any agent is involved, you can talk to the server by hand:
uv run python scripts/inspect_server.pyA ~40-line client — subprocess, newline-delimited JSON-RPC, no SDK — prints every frame in both directions:
client --> server
{ "jsonrpc": "2.0", "id": 4, "method": "tools/call",
"params": { "name": "run_query", "arguments": {
"sql": "SELECT c.name, COUNT(*) AS open_tickets FROM tickets t ..." } } }
server --> client
{ "jsonrpc": "2.0", "id": 4, "result": {
"structuredContent": { "ok": true,
"rows": [ { "name": "Lumen Retail", "open_tickets": 3 }, ... ] },
"isError": false } }The whole protocol is five messages: initialize → notifications/initialized → tools/list →
tools/call, plus resources/list and prompts/list. Everything else built on MCP is this
conversation with more ceremony.
Or use the official GUI:
uv run mcp-server --transport http --port 8765
npx @modelcontextprotocol/inspector # connect to http://127.0.0.1:8765/mcpWhat the server exposes
All three MCP primitives, not just Tools — most implementations stop at Tools.
Tools (12)
Domain | Tool | Notes |
database |
| Column types, foreign keys, row counts |
| SELECT only, enforced by SQLite itself — see below | |
calendar |
| Refuses to double-book unless |
| Working-hours aware, skips weekends and past times | |
github |
| Real REST API; PRs filtered out |
| Real writes, gated on an explicit repo |
Resources (3) — context you can pull without a tool call
db://schema · calendar://today · calendar://day/{day} (templated)
A Tool is a verb the model chooses to invoke; a Resource is a noun the client can attach up front.
Exposing the schema as a resource means the model often skips describe_schema entirely.
Prompts (3) — workflows shipped by the server
triage_issues · plan_my_week · customer_health_check
The server knows what its tools can do, so it ships the workflows rather than making every client
reinvent them. In Claude Desktop these appear as slash commands; in the CLI, /prompt <name> k=v.
The agent
A ReAct loop built by hand, because create_react_agent hides the only part worth understanding:
START ──▶ agent ──has tool calls?──▶ tools ──┐
▲ │
└────────────────────────────────┘
│
└──no──▶ ENDbuilder = StateGraph(AgentState)
builder.add_node("agent", agent)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", route, {"tools": "tools", END: END})
builder.add_edge("tools", "agent") # tool results always go back to the modelThree decisions worth pointing at:
AgentStateextendsMessagesStatewith astepscounter, androutestops the graph at a cap. A model that only ever emits tool calls is the classic runaway;recursion_limitis a blunt backstop, this is an explicit one.The server's own
instructionsdrive the agent. The MCP handshake returns aninstructionsfield, and it is folded into the system prompt. The server describes how its tools should be used — passing that through is most of what makes the agent behave.One session for the whole conversation.
MultiServerMCPClient.get_tools()without a live session reconnects per tool call, which on stdio means respawning the server every time.
Run the one-call equivalent side by side with uv run mcp-agent --prebuilt.
The CLI
uv run mcp-agent # stdio
uv run mcp-agent --transport http # against a running HTTP server
uv run mcp-agent --provider ollama # override for one runEvery tool call is traced live. The trace format below is exactly what the CLI prints, and the tool results are the real values this seed data returns — the assistant's wording is illustrative:
you which customer has the most open tickets, and when am I free tomorrow?
→ run_query(sql=SELECT c.name, COUNT(*) AS open_tickets FROM tickets t JOIN …)
✓ {"columns": ["name", "open_tickets"], "rows": [{"name": "Lumen Retail", "open_tickets": 3}, …
→ find_free_slot(duration_minutes=30, after=2026-09-15)
✓ {"slots": [{"start": "2026-09-15T09:00:00", "end": "2026-09-15T09:30:00"}, …
Lumen Retail has the most, with 3 open tickets — one urgent, one high, one
normal. Tomorrow you are free at 09:00, 09:45, 11:30 and 16:30./tools /prompts /prompt <name> k=v /resources /resource <uri> /graph /new /help
The same server in Claude Desktop
uv run python scripts/make_desktop_config.py # print the JSON
uv run python scripts/make_desktop_config.py --write # merge it in (backs up first){
"mcpServers": {
"workbench": {
"command": "/absolute/path/to/uv",
"args": ["--directory", "/absolute/path/to/MCP-powered-agent", "run", "mcp-server"]
}
}
}Restart Claude Desktop and the same 12 tools appear. Two gotchas the generator handles: Claude
Desktop launches the server from an arbitrary working directory (so the project path is passed
explicitly, and .env is resolved relative to the package, not the cwd), and it does not reliably
inherit your PATH (so uv is resolved to an absolute path).
Design decisions
SQL is read-only, and SQLite enforces it. Not a regex blocklist — the connection is opened
mode=ro and fitted with a SQLite authorizer that permits only SELECT/READ/FUNCTION, plus a
VM-step cap so a runaway join fails instead of hanging. DROP, DELETE, UPDATE, INSERT,
CREATE, ALTER, PRAGMA, ATTACH and stacked statements are each blocked, each with a test.
Tools fail structurally, not with stack traces. Every tool returns {ok, error, hint}:
{ "ok": false,
"error": "Query rejected: not authorized",
"hint": "This database is read-only. Only SELECT is permitted … Check column names with describe_schema." }A traceback tells the model nothing it can act on. A hint tells it how to retry, which is the difference between an agent that recovers and one that gives up.
GitHub payloads are trimmed before they reach the model. A raw issue is ~40 fields; _slim_issue
keeps nine and caps the body. Dumping raw API JSON into context is the easiest way to burn a token
budget.
No OAuth, no Docker, no cloud project. The calendar is real scheduling logic over SQLite rather than the Google Calendar API, so a stranger can clone this and have it working in one command.
Tests
uv run pytest # 110 tests, ~20s
uv run ruff check .No API key and no network required. The end-to-end agent tests run a real MCP server subprocess
with real tool execution and only the model faked, covering handshake → tools/list → LangChain
adaptation → graph routing → tools/call.
Two things these caught that are easy to get wrong:
"messages"stream mode emits chunks from every node, theToolNodeincluded — so tool JSON gets printed as the assistant's answer unless you filter onlanggraph_node.MCP sessions are bound to the task that opened them (anyio cancel scopes), so a pytest-asyncio generator fixture blows up on teardown. Sessions open inside the test body.
Layout
src/mcp_agent/
server/ no LangChain imports anywhere in here
app.py FastMCP app, tool/resource/prompt registration
__main__.py --transport stdio | http
db.py SQLite engine + the read-only authorizer
tools/ github.py database.py calendar.py
resources.py prompts.py
agent/
graph.py hand-built StateGraph (+ prebuilt for comparison)
llm.py anthropic | openai | ollama factory
mcp_client.py MultiServerMCPClient -> LangChain tools
cli.py Rich chat with the live tool trace
scripts/
inspect_server.py raw JSON-RPC, no SDK
make_desktop_config.py Claude Desktop wiringBuilt with mcp 1.30, langgraph 1.2, langchain-mcp-adapters 0.3, Python 3.12, uv.
Available Tools
12 toolscomment_on_issueA
Add a comment to an existing issue. Posts publicly -- confirm first.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | Markdown comment. | |
| repo | No | Repository as owner/name. | |
| issue_number | Yes | The issue number. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does reveal that the action posts publicly and advises confirmation, which is a meaningful behavior. However, it omits other relevant aspects such as authentication requirements, whether the action is reversible, or any side effects on the issue. It is better than nothing but still incomplete for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action and the key caveat. There is zero waste, and the critical warning ('confirm first') is included. It is as concise as possible while conveying essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple mutation tool, the description covers the core action and a notable behavioral note. Since an output schema exists, return values are not needed. The description does not mention error conditions or authentication, but given the tool's simplicity and the presence of a schema, it is largely sufficient. A slight gap is the lack of guidance on the optional repo parameter's behavior, but that is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each parameter having a clear description (e.g., 'Markdown comment.', 'Repository as owner/name.', 'The issue number.'). The tool description does not add any extra semantic meaning beyond what the schema already provides. Since the schema fully documents the parameters, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('Add'), a specific resource ('a comment'), and a target ('an existing issue'). This unambiguously differentiates it from sibling tools like create_issue, list_issues, or search_issues. The purpose is immediately understandable and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through its clear purpose, but it does not explicitly state when to use it versus alternatives, nor does it provide exclusions or when-not-to-use conditions. The 'confirm first' is a cautionary note but not a usage guideline. Sibling tools are distinct enough that a misroute is unlikely, but explicit guidance is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_eventA
Create a calendar event.
Refuses to double-book by default: if the slot overlaps an existing
event the call fails and returns the conflicts, so you can pick another
time (see find_free_slot) or retry with allow_conflict=true.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | End time, e.g. 2026-09-15T14:30:00. | |
| notes | No | Agenda or context. | |
| start | Yes | Start time, e.g. 2026-09-15T14:00:00. | |
| title | Yes | Short meeting title. | |
| location | No | Room name or meeting link. | |
| attendees | No | Comma-separated email addresses. | |
| allow_conflict | No | Set true to book on top of an existing event. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does it well. It discloses that double-booking is refused by default, that failures return the conflicts, and that allow_conflict overrides this behavior—details not visible in the schema's static defaults.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: one clear purpose statement followed by a focused behavioral note. Every sentence earns its place, and the primary purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create operation with an output schema and no nested objects, this description captures the key non-obvious behavior (conflict refusal) and the way to bypass it. The return format is covered by the output schema, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is already met. The description adds situational meaning for allow_conflict by framing it as a retry mechanism after a conflict, and it points to find_free_slot for alternative time selection, which is extra context beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Create a calendar event,' a specific verb and resource that clearly distinguishes this from siblings like list_events, delete_event, and create_issue. The follow-up about conflict behavior reinforces its role as the write path for calendar entries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete, actionable guidance for the overlapping-slot case: if the call fails due to a conflict, the agent can use find_free_slot to pick another time or retry with allow_conflict=true. It doesn't explicitly rule out other sibling tools, but the context is clear enough for typical use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_issueA
Open a new issue. This posts publicly -- confirm with the user first.
Include enough context in the body that someone who was not part of this conversation can act on it.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Markdown body. | |
| repo | No | Repository as owner/name. | |
| title | Yes | Issue title. | |
| labels | No | Comma-separated labels to apply. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the key non-obvious trait that creating an issue 'posts publicly' and requires user confirmation. This is substantive, though it doesn't mention permanence or side effects beyond posting.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: the action, the public/confirmation caveat, and body quality guidance. Information is front-loaded with the core purpose first, and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, consent, public visibility, and body expectations. The schema covers parameter semantics and the output schema exists. A minor gap is that the default repo behavior when 'repo' is null is not explained, but overall the tool can be invoked correctly with the provided context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes all four parameters (100% coverage), so the baseline is 3. The description adds value by specifying that the body should include enough context for someone outside the conversation to act on it, which gives meaningful guidance for the body parameter beyond the schema's 'Markdown body.'
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Open a new issue.' This clearly distinguishes it from sibling tools like list_issues, get_issue, and comment_on_issue, and the added public-posting caveat clarifies the nature of the action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit context for when to use this tool: it posts publicly, so 'confirm with the user first.' It also instructs how to format the body. However, it does not explicitly name alternatives or state when not to use the tool, leaving some inference to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_eventA
Delete a calendar event by id. Confirm with the user before calling.
| Name | Required | Description | Default |
|---|---|---|---|
| event_id | Yes | id returned by list_events. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. The confirmation instruction is useful and indicates the destructive nature of the operation, but the description does not state permanence, side effects, or authorization requirements, leaving some gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no filler, with the core action first and the important safety instruction second. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter delete tool with an output schema, the description covers the essential action and the required user confirmation. Minor missing context includes irreversible effects or error behavior, but these are not critical for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents event_id with 100% coverage: the parameter is described as the id returned by list_events. The description adds no additional parameter meaning beyond saying 'by id', so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Delete') and resource ('calendar event') and specifies the method ('by id'). It clearly distinguishes this from sibling tools like list_events and create_event.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit prerequisite: confirm with the user before calling. It does not name alternative tools, but the delete action is self-evident and the confirmation requirement supplies a clear when-not-to-call condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_schemaA
Describe columns, types and foreign keys for one table or all tables.
Always call this before writing SQL -- do not guess column names.
| Name | Required | Description | Default |
|---|---|---|---|
| table | No | Table to describe. Omit to describe every table. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It clearly states the tool is a read-only introspection operation (describing schema), which is useful. However, it doesn't disclose details like whether the output is truncated, how many tables are returned when omitted, or whether it requires any special permissions. The core behavior is transparent enough for a schema-inspection tool, but some edge-case behavior is unspecified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The first sentence states the tool's function and scope, and the second provides a critical usage directive. The imperative 'Always call this before writing SQL' is front-loaded and actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple introspection tool with one optional parameter and an output schema, the description is nearly complete. It covers what the tool does, when to use it, and the parameter semantics. The only minor gap is not describing the output format in prose, but the output schema exists and the description's directive is sufficient for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the single parameter well (table to describe, omit for all tables), and the description reinforces this by saying 'for one table or all tables.' The description adds the crucial context that omitting the parameter means all tables, which aligns with the schema's default null. Since schema coverage is 100% and the description adds a clear behavioral nuance, this is above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Describe') and resource ('columns, types and foreign keys') for either one table or all tables. It clearly distinguishes itself from siblings like list_tables (which lists table names) and run_query (which executes SQL).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs when to use this tool: 'Always call this before writing SQL -- do not guess column names.' This is a clear usage directive that tells the agent to invoke this tool as a prerequisite before run_query, and it implicitly contrasts with list_tables by focusing on schema details rather than table names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_free_slotA
Find open slots of a given length within working hours.
Returns the earliest candidates first, skipping times already in the
past. Feed one of these straight into create_event.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Earliest day to consider, YYYY-MM-DD. Defaults to today. | |
| limit | No | Max slots to return. | |
| day_end | No | Working day end, HH:MM. | 17:00 |
| day_start | No | Working day start, HH:MM. | 09:00 |
| search_days | No | How many days forward to search. | |
| skip_weekends | No | Ignore Saturday and Sunday. | |
| duration_minutes | Yes | Length of the meeting you need. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that results are ordered earliest-first, already-past times are skipped, and slots respect working-hours boundaries. It does not explicitly state that the tool is read-only, but 'Find' and 'Returns' strongly imply it. Missing details about how existing events are considered are minor because 'open slots' conveys that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no wasted words. The core purpose is front-loaded, followed by the most decision-relevant behavioral notes (ordering, past-skipping, and the create_event handoff).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 7-parameter schema with 100% coverage and an output schema, the description does not need to restate parameters or return formats. It gives the essential workflow and ordering behavior. It could mention the default search horizon and weekend skipping, but those are already in the schema, so the description is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters. The description only adds 'given length' and 'working hours', which map to duration_minutes and day_start/day_end. That is useful but not substantial beyond the schema, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Find open slots of a given length within working hours.' It clearly distinguishes this availability-search tool from sibling event tools like list_events and create_event by focusing on open slots rather than calendar records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context: return earliest candidates, skip past times, and feed results into create_event. This implies the intended workflow. However, it does not explicitly state when not to use it or name alternatives, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_issueA
Fetch one issue in full, including its body.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | No | Repository as owner/name. | |
| issue_number | Yes | The issue number. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It does disclose that the tool returns the body of the issue, which is additional context. However, it does not mention potential errors, permissions, or rate limits. For a read tool, this is acceptable but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that immediately conveys the core purpose. No filler or redundant phrases, and the key differentiator ('including its body') is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and the simplicity of the operation, the description is sufficient for an agent to understand what the tool returns. It could mention error handling or use cases more explicitly, but for a straightforward get operation it is complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters are well-documented in the schema. The description adds no parameter-specific meaning but also doesn't need to; the schema already clearly explains both repo and issue_number.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Fetch one issue') with a clear resource and distinguishes the scope ('in full, including its body'), which sets it apart from sibling tools like list_issues and search_issues that are about listing or finding issues.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool vs alternatives is provided. The description implies usage for retrieving a single issue in detail, but does not state when not to use it or when to prefer siblings like list_issues or search_issues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_eventsA
List calendar events in a date range, earliest first.
Use this to answer questions about what is on the calendar, and before scheduling anything, so you know what is already booked.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | Last day to include, YYYY-MM-DD. Defaults to 7 days out. | |
| start_date | No | First day to include, YYYY-MM-DD. Defaults to today. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of disclosing behavior. It mentions ordering ('earliest first') and implies a read operation, but does not explicitly state that it has no side effects, nor does it cover potential limitations like pagination, timezone handling, or behavior on empty ranges. For a simple read tool this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exactly two sentences. The first sentence front-loads the core function and ordering; the second adds usage context. There is zero redundancy or fluff, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with two optional parameters and an output schema, the description covers purpose, usage, and ordering. The schema handles parameter formats, and the output schema presumably documents return structure. It could benefit from an explicit 'read-only' statement, but that is implied by 'list'. Overall, an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides 100% coverage for both parameters, including format (YYYY-MM-DD) and defaults. The description only refers to 'a date range', adding no new parameter-specific detail. Per the calibration baseline, a score of 3 is appropriate when the schema fully documents parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific verb 'List', the resource 'calendar events', and the scope 'in a date range, earliest first.' This clearly differentiates it from siblings like create_event, find_free_slot, and delete_event, which have different purposes. It also explicitly ties to answering calendar questions and pre-scheduling checks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: 'Use this to answer questions about what is on the calendar, and before scheduling anything, so you know what is already booked.' It implies read-only usage and when to invoke it, but does not explicitly name alternatives or state when not to use it. Still, the guidance is actionable and sufficient for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_issuesA
List issues in a repository, newest first.
Pull requests are filtered out -- GitHub returns them from the issues endpoint too, and they are almost never what you want here.
| Name | Required | Description | Default |
|---|---|---|---|
| repo | No | Repository as owner/name. Defaults to GITHUB_DEFAULT_REPO. | |
| limit | No | Max issues to return. | |
| state | No | Filter by state: open, closed or all. | open |
| labels | No | Comma-separated label names to require. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it usefully discloses non-obvious behaviors: newest-first ordering and the filtering of pull requests returned by the GitHub issues endpoint. It does not discuss pagination, rate limits, or permissions, but the main gotcha is covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, with the core purpose and ordering front-loaded and the important PR-filter caveat second. There is no filler or redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity list operation, the description plus fully documented input schema and existing output schema cover what an agent needs: target repository, filters, limits, and the key behavioral surprise that PRs are excluded. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add parameter-level meaning beyond the notion of 'repository', but the input schema already documents all four parameters clearly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action and resource: 'List issues in a repository' with the sort order 'newest first'. It does not explicitly differentiate from the sibling search_issues, so it misses full sibling-distinguishing credit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The PR-filtering note implies a boundary ('Pull requests are filtered out') and gives useful context about what not to expect. However, it does not explicitly say when to use this tool versus alternatives such as search_issues, so usage guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tablesA
List the tables in the workbench database.
Call this first if you do not already know what data is available.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the operation is to list tables, which is inherently read-only, but it does not mention any limitations, pagination, or other behavioral nuances. The existence of an output schema covers return format, so the description is adequate but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no filler. The primary action is front-loaded, and the usage hint is placed second. Every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, parameterless tool with an output schema, the description is complete. It explains what it does and when to use it. The only minor gap is not referencing how it relates to describe_schema, but that is not critical for basic invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and schema description coverage is trivially 100%. Baseline for zero parameters is 4, and the description adds no parameter information because none exists. This is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action and resource: 'List the tables in the workbench database.' It is unambiguous about what the tool does. However, it does not explicitly contrast itself with describe_schema, which might also provide schema-related information, so it lacks sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear usage directive: 'Call this first if you do not already know what data is available.' This tells the agent when to use it, but it does not mention when not to use it or any alternatives, such as describe_schema. The guidance is useful but incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_queryA
Run one read-only SELECT against the workbench database.
Enforced by SQLite itself, not by string matching: the connection is
opened read-only and an authorizer rejects every non-read action, so
writes, DDL, PRAGMA and ATTACH all fail. Only one statement per call.
Returns the column names, the rows, and whether the result was capped.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | A single read-only SQL SELECT statement (SQLite dialect). | |
| max_rows | No | Row cap for this call. Defaults to the server limit. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and meets it thoroughly. It discloses that reads are enforced by SQLite itself through a read-only connection and an authorizer, that writes/DDL/PRAGMA/ATTACH all fail, that only one statement is allowed per call, and that the result includes column names, rows, and a capped indicator. This is exemplary behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose in its first sentence. Each subsequent sentence adds meaningful detail (enforcement mechanism, return shape) without fluff. It is appropriately sized for a tool of this complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a SQL query tool with an output schema present, the description is complete. It covers the execution model (read-only, single statement), the failure modes (non-read actions rejected), and the return shape (columns, rows, capped flag). No critical information is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description's 'Only one statement per call' mirrors the sql schema description ('A single read-only SQL SELECT statement'), and max_rows already carries its own default and purpose. The description adds no parameter semantics beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb+resource: 'Run one read-only SELECT against the workbench database.' This clearly distinguishes it from sibling tools like list_tables or create_event, which target specific operations. The added emphasis on read-only SELECT further clarifies its scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: it is the tool for arbitrary read-only SQL queries. However, it provides no explicit guidance on when to use it versus specialized siblings like list_tables or describe_schema, nor does it mention any exclusions. The context is implied but not directly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_issuesA
Search issues across GitHub using its query syntax.
Scope the search with a `repo:owner/name` qualifier unless the user
genuinely wants results from the whole of GitHub.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results. | |
| query | Yes | GitHub search syntax, e.g. 'repo:owner/name is:open label:bug timeout'. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It conveys that this is a search operation using query syntax, which implies read-only behavior, but it does not disclose details like authentication requirements, rate limits, pagination, or result-size constraints. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very concise: two sentences, with the core purpose first and the scoping advice second. Every sentence contributes useful guidance, and there is no redundant restatement of the name or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with only two parameters, full schema coverage, and an output schema, the description provides enough context for correct invocation. The main gap is the absence of any mention of authentication or rate limits, but the description's core usage guidance is sufficient for a straightforward search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both parameters with descriptions and an example, so schema description coverage is 100%. The description adds the important scoping recommendation but does not add parameter-level semantics beyond what the schema provides, matching the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches issues across GitHub using GitHub's query syntax, giving a specific verb and resource. It does not explicitly differentiate itself from sibling tools like list_issues or get_issue, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context by advising agents to scope the search with a repo:owner/name qualifier unless the user genuinely wants global results. It gives an explicit 'unless' exclusion but does not name or discuss alternative tools such as list_issues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.1.0- First observed
comment_on_issue - First observed
create_event - First observed
create_issue - First observed
delete_event - First observed
describe_schema - First observed
find_free_slot - First observed
get_issue - First observed
list_events - First observed
list_issues - First observed
list_tables - First observed
run_query - First observed
search_issues
TDQS
Scored across 12 tools
The tools form three clear clusters—database, calendar, and GitHub issues—and within each cluster every tool has a distinct resource and action. Even similar-sounding tools like list_events vs find_free_slot and list_issues vs search_issues are clearly separated by their descriptions.
All tool names follow a consistent lowercase snake_case verb_noun pattern, such as list_tables, create_event, delete_event, and get_issue. The singular/plural distinction (list_issues vs get_issue) is also applied predictably.
Twelve tools is well within the ideal range, and each tool serves a distinct, justified purpose across the three subdomains. There is no apparent bloat or redundancy.
The database read-only surface is complete, and calendar/issue creation and reading are covered, but there are notable gaps: no event update/reschedule tool and no issue update/close tool. Agents can work around some gaps but cannot fully manage issue state or reschedule events cleanly.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceExposes MCP tools that enable remote LLMs to query local Docker containers, OS processes, and system services in real time.-
- FlicenseNot gradedqualityCmaintenanceExposes task management (add, list, complete tasks) and document search (RAG) as MCP tools for AI agents.-
- AlicenseBqualityAmaintenanceExposes ACR's memory, skill, web, and GitHub search tools to any MCP client, enabling task execution and tool access via the MCP protocol.64MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI clients to connect to example tools, resources, and prompts over MCP, demonstrating integration with IDEs, chatbots, and agent frameworks.-