Starspace logoStarspace
    /Docs

    Agent Skills

    How to use the Starspace MCP server effectively from an AI agent. Optimized to be pasted into a system prompt - copy this whole page with the button below.

    Agent Skills - Starspace MCP

    How an AI agent should use the Starspace MCP server effectively. Drop this into your agent's system prompt or context.

    Golden path

    For a question                   →   ask     (one call, returns a synthesized answer with citations)
    For deeper / multi-file work     →   1. search  → find candidate files (ranked, with confidence + why)
                                         2. fetch   → read the exact span suggested by search
                                         3. rg/grep → verify exact strings if needed (via run_readonly)
                                         4. edit    → write_file / apply_patch when you're sure
    

    A typical agent turn for "what is this codebase?"-style questions is one ask call. A typical investigation turn never needs more than 3–4 tool calls (search → fetch → optional rg → done). If you find yourself making 8+ calls, you're probably searching when you should be reading, or guessing at file paths instead of asking.

    When to use what

    You want to…Use
    Get a synthesized answer to a question about the codebaseask
    Find files by topic, identifier, or conceptsearch
    Find an exact string after you've narrowed candidatesrg (via run_readonly)
    Read the contents of a known filefetch
    Browse a directory treerun_readonly with tree/ls
    Get a feel for a workspace (file counts, top extensions)workspace_summary
    Edit a file you've already readapply_patch (preferred) or write_file

    Rules of thumb:

    • ask is for "how does X work", "where is Y configured", "what does Z do". One call, structured answer + citations.
    • search is for "where is X?" when you want the candidate file list (not an answer).
    • rg is for "show me every line that says X." Don't rg the whole workspace looking for an unfamiliar concept - search is faster and ranked.
    • If ask returns confidence: "low", drop down to search + fetch and reason over the contents yourself.

    Using search well

    Pass a real query

    A good query has 3–8 specific tokens. auth is too vague. stripe webhook signature verification is great.

    { "name": "search", "arguments": { "query": "stripe webhook signature verification", "limit": 5 } }
    

    Optional inputs you should know

    InputWhen to use
    limitSet 3–5 when you only want the top hit; 10–20 when comparing options.
    path_prefixWhen you know the area: "src/auth" or "docs/".
    file_globWhen you want one file type: "*.md" or "**/*_test.py".
    modeOverride the auto-classifier. exact for identifiers; semantic for prose; debug for error/log queries. auto is right ~95% of the time.

    Reading the response

    Each result has an id, path, score (0–1), confidence (high/medium/low), and - when reranking ran - a why rationale and rerank_rank. The why field tells you whether to fetch or skip without reading the snippet.

    {
      "id": "file:src/api_router.py:L7-L42",
      "path": "src/api_router.py",
      "score": 1.0,
      "confidence": "high",
      "rerank_rank": 1,
      "why": "Canonical FastAPI router for OpenAI chat completion routes",
      "matched_lines": [{ "line": 12, "text": "@router.post('/v1/chat/completions')" }]
    }
    

    If confidence is high, fetch it. If medium, read why and matched_lines first. If low, your query is probably wrong - refine and re-search.

    Citation IDs

    When a result has a known span, id looks like file:<path>:L<start>-L<end>. Pass that id straight to fetch - the line range is parsed automatically; you don't need to set start_line/end_line separately. This is the fastest way to land on the relevant code.

    query_interpretation - debug your queries

    Every search returns a query_interpretation block:

    {
      "mode_used": "semantic",
      "intent_detected": "semantic",
      "filters_applied": { "limit": 5 },
      "reranked": true,
      "rerank_reason": "applied"
    }
    

    rerank_reason tells you why reranking did or didn't happen:

    ValueMeaningWhat to do
    appliedReranker ranked the resultsYou're set.
    no_resultsEmpty resultsRefine the query - likely too specific or wrong terms.
    too_few_candidates≤3 resultsLoosen the query if those 3 don't match.
    exact_modeIdentifier-shaped querySymbol tier handled it; rerank wasn't needed.
    disabledReranking off on this serverTreat raw RRF order as a hint, not gospel.
    gemini_errorReranker call failedOrder is original RRF; retry the same query if needed.

    Using fetch well

    Pass the search id directly

    { "name": "fetch", "arguments": { "id": "file:src/api_router.py:L7-L42" } }
    

    This returns exactly lines 7–42 of src/api_router.py. No prep needed.

    Override the range when you need more context

    { "name": "fetch", "arguments": { "id": "file:src/api_router.py:L7-L42", "start_line": 1, "end_line": 80 } }
    

    The explicit start_line/end_line win over the embedded range. Use this when search points at the right region but you need imports or surrounding helpers. Capped at 2000 lines per call.

    Don't fetch a whole file unless you need to

    If a search hit gives you L40-L80, fetch just that. Fetching whole files is the agent equivalent of cat-ing every file you suspect - burns context for no reason.

    Using rg for exact strings

    rg (workspace-native ripgrep) and grep are the right move when you want to verify an exact string occurs and where:

    {
      "name": "run_readonly",
      "arguments": { "command": "rg --json -t py 'create_chat_completion' src/" }
    }
    

    Available read commands: ls, tree, cat, head, tail, find, grep, rg, outline, diff, wc, sort, uniq, xargs, stat, lines, echo. Chain with |, &&, ||, ;, or newlines.

    rg supports the most common flags but is not full ripgrep. If a flag is rejected, the error message lists supported alternatives. rg --files lists files without searching content.

    Editing files

    Always read a file before editing it - don't write blind. The server tracks per-session reads as a guardrail.

    apply_patch (preferred for surgical edits)

    *** Begin Patch
    *** Update File: src/api_router.py
    @@@ -10,3 +10,5 @@@
     import { foo } from './foo';
    -import { bar } from './bar';
    +import { bar } from './bar';
    +import { baz } from './baz';
     const app = createApp();
    *** End Patch
    

    write_file (for new files or full rewrites)

    { "name": "write_file", "arguments": { "path": "src/new.ts", "content": "..." } }
    

    Pass complete file content, not a diff. Overwrites if the file exists.

    run for shell-level edits

    run (full route, not /readonly/) supports write, rm, patch, fetch, note. Use this when you need to mv/rm files or chain operations.

    Common failure modes

    SymptomLikely causeFix
    Search returns no resultsQuery too specific or wrong termsDrop adjectives; try fewer, more central tokens
    Top result has confidence: lowQuery mismatchedAdd path_prefix or use mode: "exact" if you have an identifier
    Fetch returns wrong spanPass the id exactly as search returned itDon't construct file:<path> ids by hand - they may miss the line range
    apply_patch failsFile changed between read and patch, or context lines don't matchRe-fetch, re-author the patch
    401 UnauthorizedAPI key missing/invalidCheck Authorization: Bearer ak_... header
    403 ForbiddenInsufficient scopeNeed workspace:write for write tools, workspace:read or workspace:ask for everything else
    429 Too Many RequestsRate limit (120/min/workspace)Back off and retry

    Quick reference

    search    → ranked discovery, returns id you pass to fetch
    fetch     → read a citation. id form: file:<path>:L<s>-L<e>
    run_readonly → rg, grep, ls, tree, cat, head, tail, find, etc.
    run       → same as run_readonly + write/rm/patch/fetch/note (write route only)
    write_file   → create or overwrite file (write route only)
    apply_patch  → surgical edit (write route only)
    workspace_summary → high-level workspace stats
    server_health    → diagnostics, toolset hash
    

    See also