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
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:
- Header line:
<owner>/<repo> issues (state=<state>, count=<n>)
- One line per issue:
#<number> [<state>] <title> — <html_url>
- 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.
Parent / Anchor issue:
#1
Goal
Build the first runnable MCP server for this repository, strictly following the established design decisions from the legacy
lebduska/sparingpartnerMCP.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
"type": "module").@modelcontextprotocol/sdkzodoctokitProject structure (exact paths)
package.jsonsrc/index.jssrc/tools.jsREADME.md(extend only; do not rewrite existing sections)package.json requirements
name: "uplink-issues"type: "module"dev:node src/index.jstest:node --testMCP server
new McpServer({ name: "uplink-issues", version: "0.1.0" })src/tools.js.Authentication
GITHUB_TOKENGH_TOKENGITHUB_PATTool: list_issues (READ only)
Name
list_issuesInput schema (zod)
owner: string (required)repo: string (required)state: enumopen | closed | all(optional, default:open)per_page: integer 1–100 (optional, default:20)Behavior
GET /repos/{owner}/{repo}/issuesusing Octokit.stateandper_pagedirectly to the API.pull_requestfield).Output (strict)
text.<owner>/<repo> issues (state=<state>, count=<n>)#<number> [<state>] <title> — <html_url>{ "owner": "...", "repo": "...", "state": "...", "count": <n>, "issues": [ ... ] }README update
npm run dev)Out of scope
Acceptance criteria
npm installfollowed bynpm run devstarts the MCP server successfully.list_issuesworks on a public repository.Notes
If anything is unclear or missing: