Skip to main content
Glama

Run code against Sinatra's tools

run_code
Destructive

Run a JavaScript async arrow function that calls Sinatra's tools as functions, to chain, filter or loop over them in one step and return only what you need.

declare const sinatra: { /** Show the Sinatra user this connection acts as and the workspaces they belong to, with their role in each. The workspace ids are the workspace_id the other tools take. Reads only. / whoami(args?: {}): Promise; /* List a workspace's tasks, most recently active first, with each task's status, repository and pull request. Use it to find a task or see what's running; pass nextCursor as cursor for the next page. Reads only. / list_tasks(args: { workspace_id: string; // The workspace id (from whoami). status?: string; // Only tasks in this status, e.g. implementing or pr_open. limit?: number; cursor?: string; // nextCursor from the previous page. }): Promise; /* Get one task's status, title, repository and pull request. Works for any task in the workspace, wherever it started. Reads only. / get_task(args: { workspace_id?: string; // The task's workspace id (from whoami). Optional: Sinatra finds it from task_id. task_id: string; // The task id (from list_tasks). }): Promise; /* Start a new coding task in a workspace. Sinatra's agent works on the prompt in its own sandbox and answers in the task's conversation. Depending on the prompt, it may push a branch and open a pull request in a connected GitHub repository. Each call starts a separate task unless it repeats an earlier idempotency_key. The task's url is its page in the Sinatra dashboard, where a person can follow it and reply. / start_task(args: { workspace_id: string; // The workspace id (from whoami). prompt: string; // What to do, as you'd ask a teammate. title?: string; // A short title; defaults to the prompt's first line. repo?: string; // owner/name of a connected repository. Omit to let the agent choose. model?: string; // A model id from Sinatra's catalog, such as anthropic/claude-opus-5-5 or openai-codex/gpt-6.1-sol, for every agent on this task. Omit to use the repository's or workspace's model. idempotency_key?: string; // Retrying with the same key returns the same task instead of starting another. }): Promise; /* Send a message on a task started with start_task, such as an answer to the agent's question or a change of plan. A message sent while an agent is working waits and starts the next agent. A task that has stopped picks up again, and the agent may push more commits to the task's pull request. / follow_up(args: { workspace_id?: string; // The task's workspace id (from whoami). Optional: Sinatra finds it from task_id. task_id: string; // The task id (from list_tasks). text: string; idempotency_key?: string; // Retrying with the same key sends the message once. }): Promise; /* Read the conversation of a task started with start_task, oldest first: your messages, the agent's answers and questions, and Sinatra's notices. Pass after to read only newer messages. Reads only. / get_messages(args: { workspace_id?: string; // The task's workspace id (from whoami). Optional: Sinatra finds it from task_id. task_id: string; // The task id (from list_tasks). after?: string; // The id of the last message already read (or next from the previous page). limit?: number; }): Promise; /* Stop the agent working on a running task, interrupting the work in progress. Works for any task in the workspace, wherever it started; any member may stop any task, a teammate's included. / stop_task(args: { workspace_id?: string; // The task's workspace id (from whoami). Optional: Sinatra finds it from task_id. task_id: string; // The task id (from list_tasks). }): Promise; /* Search the open Linear and GitHub issues you could delegate to Sinatra: yours first, then your team's unassigned ones, leaving out issues assigned to someone else or already being worked on. Pass a ticket to delegate_ticket: for Linear, its identifier as id; for GitHub, its identifier's owner/name as repo and number. linear and github say whether each tracker is connected and your Linear account linked. Reads only. / search_tickets(args: { workspace_id: string; // The workspace id (from whoami). query?: string; // Text to match: GitHub search terms, or a substring of a Linear issue's title. Omit to list without filtering. repo?: string; // owner/name of a connected repository to search first on GitHub. }): Promise; /* Hand an existing Linear issue or GitHub issue to Sinatra as you, as if you'd assigned it to Sinatra yourself. Sinatra assigns or labels the issue, and its agent may push a branch and open a pull request. The task's conversation stays on that issue (follow_up and get_messages don't apply); list_tasks shows its progress. */ delegate_ticket(args: { workspace_id: string; // The workspace id (from whoami). source: "linear" | "github"; id?: string; // Linear only: the issue identifier (e.g. ENG-123) or id. repo?: string; // GitHub only: owner/name of a connected repository. number?: number; // GitHub only: the issue number. }): Promise; };

Each function resolves with the JSON its tool returns, and throws an Error with the tool's message when the tool refuses. Calls run as you, with the same checks as calling the tool directly. console.log output comes back as logs. There is no network, filesystem or timer access.

Per run: at most 50 tool calls, 200 ms of computation and 30 s in all; return at most 50,000 characters of JSON.

Example: async () => { const { workspaces } = await sinatra.whoami(); const { tickets } = await sinatra.search_tickets({ workspace_id: workspaces[0].id, query: "flaky" }); return tickets.map((t) => t.identifier); }

Input Schema

NameRequiredDescriptionDefault
codeYesAn async arrow function, like async () => { ... }; what it returns is the result.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds a great deal beyond the annotations: per-run quotas (50 tool calls, 200 ms compute, 30 s wall clock, 50,000 characters of returned JSON), no network/filesystem/timer access, console.log surfaced as logs, and Errors thrown with the tool's own message on refusal. It also clarifies that embedded calls run as the caller under the same checks, which is exactly the context needed given destructiveHint=true and openWorldHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The key framing sentence is front-loaded, and the runtime constraints plus example are grouped after the embedded API declarations. The body is long, but nearly all of it is the typed surface of the nine callable tools, which the agent needs in order to write correct code; it is sized for the task rather than padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description fills that gap by explaining that each function resolves with the tool's JSON and that the run returns the function's value under a character cap. Limits, error semantics, sandbox restrictions, and an example together cover everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter is already described as an async arrow function, so the baseline is high. The description still adds value by specifying that the function's return value becomes the result, that you should return only what you need, and by giving a worked example of the code shape.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb and mechanism: run a JS async arrow function that calls Sinatra's tools as functions. It also states the payoff (chain, filter, loop in one step), which distinguishes it from every sibling, all of which are single direct tool calls.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It says when to reach for this tool: chaining, filtering, or looping over several tool calls and returning only what you need. It stops short of naming the alternative explicitly (call list_tasks or get_task directly when you just need one result), so the boundary with the siblings is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources