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 |
Capabilities
Features and capabilities supported by this server
| 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
- 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