Skip to content

EXEC: MCP server skeleton (stdio) with 1 READ tool (list_issues) #9

@lebduska

Description

@lebduska

Parent / Anchor issue:
#1


Goal
Build the first runnable MCP server for this repository, strictly following the established design decisions from the legacy lebduska/sparingpartner MCP.

This issue is meant to validate the full workflow (issue → Copilot → PR → CR → merge) with real code, while keeping scope intentionally minimal and deterministic.


Scope

Technology & runtime

  • Node.js >= 18 (ESM only, "type": "module").
  • Use exactly these dependencies (no others):
    • @modelcontextprotocol/sdk
    • zod
    • octokit

Project structure (exact paths)

  • package.json
  • src/index.js
  • src/tools.js
  • README.md (extend only; do not rewrite existing sections)

package.json requirements

  • Must include:
    • name: "uplink-issues"
    • type: "module"
    • scripts:
      • dev: node src/index.js
      • test: node --test
  • Dependencies must be explicitly listed (versions may follow current stable ranges).

MCP server

  • Transport: stdio only (no HTTP, no SSE, no web server).
  • Server initialization:
    • new McpServer({ name: "uplink-issues", version: "0.1.0" })
  • Tool registration must be delegated to src/tools.js.
  • No side effects at import time.

Authentication

  • GitHub token resolution order:
    • GITHUB_TOKEN
    • GH_TOKEN
    • GITHUB_PAT
  • If no token is present, the tool must return a single text response explaining how to set it.

Tool: list_issues (READ only)

Name

  • list_issues

Input schema (zod)

  • owner: string (required)
  • repo: string (required)
  • state: enum open | closed | all (optional, default: open)
  • per_page: integer 1–100 (optional, default: 20)

Behavior

  • Call GitHub REST API: GET /repos/{owner}/{repo}/issues using Octokit.
  • Pass state and per_page directly to the API.
  • Filter out pull requests (entries with pull_request field).

Output (strict)

  • The tool must return exactly ONE MCP content item of type text.
  • Text format:
    1. Header line: <owner>/<repo> issues (state=<state>, count=<n>)
    2. One line per issue: #<number> [<state>] <title> — <html_url>
    3. Final JSON block (valid JSON, last in output):
      {
        "owner": "...",
        "repo": "...",
        "state": "...",
        "count": <n>,
        "issues": [ ... ]
      }

README update

  • Add a Run section describing:
    • required Node version
    • environment variable for GitHub token
    • command to start the MCP server (npm run dev)
  • Do not modify or rephrase existing README sections.

Out of scope

  • Any WRITE operations (create/update/comment/close/reopen issues)
  • Any additional MCP tools
  • HTTP or SSE transports
  • GitHub App or JWT authentication
  • Repository allow-lists or persistence
  • Autonomous or background behavior

Acceptance criteria

  • npm install followed by npm run dev starts the MCP server successfully.
  • MCP client can connect via stdio and list available tools.
  • list_issues works on a public repository.
  • Output contains no pull requests.
  • Tool output consists of a single MCP content item.
  • No extra files, tools, or dependencies are introduced.

Notes
If anything is unclear or missing:

  • Stop implementation.
  • Ask via a comment on this issue.
  • Do not guess or extend scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions