SAIR MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| SAIR_API_KEY | Yes | Your personal SAIR API key. The server refuses to start without it. | |
| SAIR_BASE_URL | No | Override for testing against a different environment. | https://api.sair.foundation/api/public/v1 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_meA | Return the API key in use and its owner. Scope: none -- works with any valid key. Call this first to verify a key is valid and to inspect its granted scopes before calling scope-gated endpoints. |
| list_cheatsheetsB | List cheatsheets owned by the calling account (content omitted). Scope: playground.read. |
| get_cheatsheetB | Get one cheatsheet, including its content body. Scope: playground.read. |
| create_cheatsheetA | Create a cheatsheet owned by the calling account. Scope: playground.write. Can be referenced from a Playground run (configurations[].cheatsheet) and submitted to a cheatsheet-kind competition. |
| update_cheatsheetA | Partially update a cheatsheet. Provide at least one field. Scope: playground.write. Raises CHEATSHEET_LOCKED (403) if the cheatsheet is currently published on the Contributor Network -- withdraw it first. |
| delete_cheatsheetA | Delete a cheatsheet owned by the calling account. Scope: playground.write. Raises CHEATSHEET_LOCKED (403) if published on the Contributor Network -- withdraw it first. |
| list_competitionsA | List competitions visible through the public API. Scope: competition.read. Cursor-paginated (default limit 25, max 100): pass the previous response's nextCursor to fetch the next page; a nextCursor of null means there are no more pages. |
| get_competitionA | Get one competition's detail, including its submissionSpec. Scope: competition.read. submissionSpec (schema, metaSchema, permission, window, limits, catalog) is the only source of truth for how to build a submission payload for this competition -- read it before calling submit_competition_entry or submit_playground_run. |
| get_my_participationA | Get the caller's participation status in one competition. Scope: competition.read. Returns canSubmit and, when false, submitBlockedReason (EMAIL_NOT_VERIFIED, NOT_ENROLLED, NOT_TEAM_OWNER, BEFORE_WINDOW, AFTER_WINDOW). Treat this as the source of truth for whether a submission should be attempted right now. |
| get_leaderboardA | List published leaderboard rows for a competition. Scope: competition.read. Cursor-paginated. Always returns 200; use data.meta.published (not the emptiness of items) to tell whether the leaderboard has been published yet. |
| get_my_leaderboard_standingA | Get the caller's own leaderboard entry for a competition. Scope: competition.read. Returns {"entry": null} when the caller isn't ranked yet (no team, no scoring placements, or leaderboard unpublished). |
| submit_competition_entryA | Create or replace the caller's submission for a competition. Scope: competition.write.
|
| get_my_submissionA | Get the caller's current submission for a competition. Scope: competition.read. For cheatsheet / model-reference /
solver-participation this returns a single submission record (404 if
none exists yet); pass |
| get_submission_by_idA | Get one submission by ID. Scope: competition.read. The caller can only read submissions they are allowed to access for this competition. |
| download_submission_textA | Download the stored text body of a submission as plain text. Scope: competition.read. Returns payload.content (cheatsheet), payload.solverCode (solver-participation), or newline-joined payload.polynomials (igp24-polynomial). Raises NO_DOWNLOAD_FOR_KIND for model-reference submissions, which have no text body. |
| get_igp24_label_progressA | Get aggregate IGP24 participant progress by transitive group label. Scope: competition.read. Bulk aggregate endpoint over the ~25,000-label
IGP24 universe; returns data.labels[] rather than data.items[]. Before
publication returns labels: [], meta.published: false. |
| list_contributor_network_itemsA | List visible Contributor Network items (content/solverCode/model fields omitted). Scope: contributor-network.read. |
| get_contributor_network_itemA | Get one Contributor Network item with its full payload. Scope: contributor-network.read. Includes |
| publish_contributor_network_itemA | Publish a saved resource, a submitted text body, inline text, or a model reference. Scope: contributor-network.write. |
| withdraw_contributor_network_itemA | Withdraw (unpublish) an item authored by the calling account. Scope: contributor-network.write. Withdrawn items disappear from listings, direct lookups, graphs, and benchmark results. |
| favorite_contributor_network_itemA | Set the caller's favorite flag for an item (idempotent). Scope: contributor-network.write. |
| unfavorite_contributor_network_itemA | Clear the caller's favorite flag for an item (idempotent). Scope: contributor-network.write. Refetch the item to read the updated favoriteCount. |
| list_contributor_network_commentsA | List comments on an item, oldest first. Scope: contributor-network.read. Soft-deleted comments remain for thread continuity with body/author.displayName set to null. |
| create_contributor_network_commentA | Create a comment on an item. Scope: contributor-network.write. |
| delete_contributor_network_commentA | Soft-delete a comment. Scope: contributor-network.write. Callers may delete their own comments; item authors may delete any comment on their own items. |
| get_contributor_network_item_graphA | Get the lineage subgraph rooted at one item (ancestors + descendants). Scope: contributor-network.read. |
| get_contributor_network_global_graphA | Get the lineage graph across all visible items. Scope: contributor-network.read. Capped at 2000 nodes -- add
|
| list_contributor_network_benchmarksA | List platform-run benchmark summaries for published items. Scope: contributor-network.read. Benchmarks are platform-scheduled, not
user-triggered. |
| get_contributor_network_item_benchmarkC | Get the per-model benchmark breakdown for one item. Scope: contributor-network.read. |
| list_custom_problemsC | List private Lean statement pairs (custom problems) owned by the calling account. Scope: playground.read. |
| get_custom_problemA | Get one custom Lean problem owned by the calling account. Scope: playground.read. |
| create_custom_problemA | Create an immutable private Lean statement pair. Scope: playground.write. |
| delete_custom_problemA | Delete a custom Lean problem owned by the calling account. Scope: playground.write. Existing runs that referenced the problem keep their own stored copy and history. |
| list_playground_modelsA | List Playground model IDs accepted in a run for this competition. Scope: playground.read. Only call this when the competition's
capabilities.playground is true. Model IDs are opaque tokens (some are
OpenRouter-style |
| list_playground_problem_setsC | List Playground problem sets available for practice runs. Scope: playground.read. |
| get_playground_problem_setB | Get every problem in one Playground problem set (not paginated). Scope: playground.read. Row shape depends on competition kind: equation problems (index, equation1, equation2, goldAnswer) for cheatsheet competitions, Lean problems (id, lhsName, lhsText, rhsName, rhsText, isCustom) for solver-participation competitions. |
| submit_playground_runA | Create a Playground practice run. Scope: playground.write.
Returns {"runId": ..., "status": "pending"}. Poll get_playground_run / list_playground_run_results for progress. |
| list_playground_runsB | List Playground runs created by the caller for this competition. Scope: playground.read. |
| get_playground_runB | Get one Playground run: params, summary, and timing. Scope: playground.read. Lean competitions also include verdicts[]. |
| cancel_playground_runA | Cancel a pending or running Playground run. Scope: playground.write. Already-terminal runs raise RUN_NOT_CANCELLABLE (409). |
| list_playground_run_resultsA | List per-cell/per-problem result rows for a Playground run. Scope: playground.read. Row shape depends on competition kind (equation / Lean / model-reference result fields). |
| stream_playground_run_eventsA | Collect Server-Sent Events for a solver-participation Playground run. Scope: playground.read. Only available for solver-participation
competitions. This blocks for up to |
| get_playground_usageA | Get the caller's accumulated Playground practice spend for this competition. Scope: playground.read. Returns credit balance, run counters, and either cellsExecuted (equation-style) or problemsAttempted (Lean / model-reference). |
| list_solver_templatesA | List solver templates owned by the calling account (solverCode omitted). Scope: playground.read. |
| get_solver_templateB | Get one solver template, including its Lean 4 solverCode. Scope: playground.read. |
| create_solver_templateA | Create a solver template owned by the calling account. Scope: playground.write. |
| update_solver_templateA | Partially update a solver template. Provide at least one field. Scope: playground.write. |
| delete_solver_templateA | Delete a solver template owned by the calling account. Scope: playground.write. Raises SOLVER_TEMPLATE_LOCKED (403) if published on the Contributor Network -- withdraw it first. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/osick/SAIRmcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server