Skip to content

Commit b4d16bf

Browse files
authored
Add mcp-server cookbook (#400)
1 parent 834a5a1 commit b4d16bf

3 files changed

Lines changed: 290 additions & 0 deletions

File tree

mcp-server/.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# GitHub personal access token — https://github.com/settings/tokens
2+
# Requires: repo scope (read issues, PRs, commits)
3+
# Used by both the GitHub dataset connector and the GitHub MCP server (via env: in spicepod.yaml).
4+
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_...
5+
6+
# Optional: Jira and Confluence (uncomment tools.jira in spicepod.yaml to use)
7+
# JIRA_URL=https://your-org.atlassian.net
8+
# JIRA_USERNAME=your@email.com
9+
# JIRA_API_TOKEN=...

mcp-server/README.md

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# Spice as MCP Server
2+
3+
Works with `v1.0+`
4+
5+
Run Spice as an MCP server and connect your AI assistant (Claude Desktop, Cursor, VS Code, or any MCP client) to it. This recipe loads GitHub issues, pull requests, and commits as accelerated, in-memory datasets and exposes the [GitHub MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/github) through a single unified endpoint at `/v1/mcp`.
6+
7+
Your AI assistant gets one connection point that gives it:
8+
9+
| Tool | What it does |
10+
|------|-------------|
11+
| `sql` | Sub-millisecond SQL over accelerated GitHub data |
12+
| `github/*` | Write tools — create issues, comment on PRs, search code |
13+
| `list_datasets`, `table_schema` | Schema discovery |
14+
| `search`, `top_n_sample`, `sample_distinct_columns` | Data exploration |
15+
16+
```
17+
Claude Desktop / Cursor / any MCP client
18+
19+
│ Streamable HTTP http://localhost:8090/v1/mcp
20+
21+
┌─────────────────────────────────────────────────┐
22+
│ SPICE │
23+
│ │
24+
│ built-in tools │
25+
│ sql, list_datasets, table_schema, │
26+
│ search, top_n_sample, ... │
27+
│ │
28+
│ github/* ── stdio ──► npx @mcp/server-github │
29+
│ │
30+
│ datasets (Arrow, in-memory) │
31+
│ github_issues ◄── GitHub API │
32+
│ github_pulls ◄── GitHub API │
33+
│ github_commits ◄── GitHub API │
34+
└─────────────────────────────────────────────────┘
35+
```
36+
37+
> **Want to add Jira?** Uncomment the `jira` tool block in `spicepod.yaml` and add your Jira credentials to `.env`. See [Adding Jira](#optional-adding-jira) below.
38+
39+
## Prerequisites
40+
41+
- [Spice CLI](https://docs.spiceai.org/getting-started) installed
42+
- [Node.js](https://nodejs.org) — for `npx` to launch the GitHub MCP server
43+
- A [GitHub personal access token](https://github.com/settings/tokens) with `repo` scope
44+
45+
## Setup
46+
47+
**Step 1.** Clone the cookbook and navigate to this recipe:
48+
49+
```bash
50+
git clone https://github.com/spiceai/cookbook.git
51+
cd cookbook/mcp-server
52+
```
53+
54+
**Step 2.** Create a `.env` file:
55+
56+
```bash
57+
cp .env.example .env
58+
```
59+
60+
Edit `.env` and set your GitHub token:
61+
62+
```env
63+
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_...
64+
```
65+
66+
> The same token is used by both the GitHub dataset connector and the GitHub MCP server subprocess. Spice injects it via the `env:` block in `spicepod.yaml`.
67+
68+
**Step 3.** Start Spice:
69+
70+
```bash
71+
spice run
72+
```
73+
74+
Spice loads GitHub data into memory and launches the GitHub MCP server subprocess. Expect the initial load to take 20–60 seconds.
75+
76+
```console
77+
2025-05-21T10:00:01Z INFO runtime: Spice runtime is ready
78+
2025-05-21T10:00:01Z INFO runtime::init::dataset: Dataset github_issues registered (github:...), acceleration (arrow)
79+
2025-05-21T10:00:01Z INFO runtime::init::dataset: Dataset github_pulls registered (github:...), acceleration (arrow)
80+
2025-05-21T10:00:01Z INFO runtime::init::dataset: Dataset github_commits registered (github:...), acceleration (arrow)
81+
2025-05-21T10:00:01Z INFO runtime::init::tool: Tool github registered (mcp:npx)
82+
```
83+
84+
**Step 4.** Confirm the unified tool catalog is available (in a new terminal):
85+
86+
```bash
87+
curl -s http://127.0.0.1:8090/v1/tools -H "X-API-KEY: foo" | jq '.[].name'
88+
```
89+
90+
```
91+
"sql"
92+
"list_datasets"
93+
"table_schema"
94+
"search"
95+
"top_n_sample"
96+
"random_sample"
97+
"sample_distinct_columns"
98+
"get_readiness"
99+
"load_memory"
100+
"store_memory"
101+
"github/create_issue"
102+
"github/list_issues"
103+
"github/get_pull_request"
104+
"github/list_pull_requests"
105+
"github/search_code"
106+
"github/search_repositories"
107+
...
108+
```
109+
110+
Built-in tools (`sql`, `list_datasets`, ...) and proxied GitHub MCP tools (`github/*`) appear together in one catalog.
111+
112+
## Connect Claude Code
113+
114+
Run this once to register Spice as an MCP server in Claude Code:
115+
116+
```bash
117+
claude mcp add --transport http spice http://localhost:8090/v1/mcp --header "X-API-KEY: foo"
118+
```
119+
120+
Verify it was added:
121+
122+
```bash
123+
claude mcp list
124+
```
125+
126+
```
127+
spice: http://localhost:8090/v1/mcp (http)
128+
```
129+
130+
Claude Code will now have access to the full Spice tool catalog — `sql`, `github/*`, `list_datasets`, and the rest — in every conversation.
131+
132+
## Example queries
133+
134+
Once connected, ask your AI assistant questions like:
135+
136+
- *"Show me the 10 most recently merged PRs."*
137+
- *"Who are the top 5 contributors by number of commits in the last 30 days?"*
138+
- *"What issues were opened this week and are still unassigned?"*
139+
140+
### SQL against the accelerated data (direct API)
141+
142+
Count issues by state:
143+
144+
```bash
145+
curl -s -XPOST http://127.0.0.1:8090/v1/tools/sql \
146+
-H "Content-Type: application/json" \
147+
-H "X-API-KEY: foo" \
148+
-d '{"query": "SELECT state, COUNT(*) AS n FROM github_issues GROUP BY state ORDER BY n DESC"}'
149+
```
150+
151+
```json
152+
[{"type":"text","text":"[{\"state\":\"OPEN\",\"n\":1},{\"state\":\"CLOSED\",\"n\":1}]"}]
153+
```
154+
155+
Top contributors by commits:
156+
157+
```bash
158+
curl -s -XPOST http://127.0.0.1:8090/v1/tools/sql \
159+
-H "Content-Type: application/json" \
160+
-H "X-API-KEY: foo" \
161+
-d '{"query": "SELECT author_name, COUNT(*) AS commits FROM github_commits GROUP BY author_name ORDER BY commits DESC LIMIT 5"}'
162+
```
163+
164+
```json
165+
[{"type":"text","text":"[{\"author_name\":\"Sergei Grebnov\",\"commits\":74},{\"author_name\":\"Luke Kim\",\"commits\":45},..."}]
166+
```
167+
168+
PRs merged in the last 7 days:
169+
170+
```bash
171+
curl -s -XPOST http://127.0.0.1:8090/v1/tools/sql \
172+
-H "Content-Type: application/json" \
173+
-H "X-API-KEY: foo" \
174+
-d '{"query": "SELECT number, title, merged_at FROM github_pulls WHERE state = '\''MERGED'\'' AND merged_at >= now() - INTERVAL '\''7 days'\'' ORDER BY merged_at DESC"}'
175+
```
176+
177+
### GitHub MCP tools (direct API)
178+
179+
Search code across the repository:
180+
181+
```bash
182+
curl -s -XPOST http://127.0.0.1:8090/v1/tools/github/search_code \
183+
-H "Content-Type: application/json" \
184+
-H "X-API-KEY: foo" \
185+
-d '{"q": "java repo:spiceai/cookbook"}'
186+
```
187+
188+
## Optional: Adding Jira
189+
190+
To expose Jira and Confluence tools through the same MCP endpoint, add credentials to `.env`:
191+
192+
```env
193+
JIRA_URL=https://your-org.atlassian.net
194+
JIRA_USERNAME=your@email.com
195+
JIRA_API_TOKEN=...
196+
```
197+
198+
Uncomment the `jira` tool block in `spicepod.yaml`:
199+
200+
```yaml
201+
- name: jira
202+
from: mcp:uvx
203+
description: Jira and Confluence tools — query tickets, update status, search projects
204+
params:
205+
mcp_args: mcp-atlassian
206+
env:
207+
JIRA_URL: ${secrets:JIRA_URL}
208+
JIRA_USERNAME: ${secrets:JIRA_USERNAME}
209+
JIRA_API_TOKEN: ${secrets:JIRA_API_TOKEN}
210+
```
211+
212+
Restart Spice. Jira tools appear in the same catalog alongside GitHub and SQL:
213+
214+
```bash
215+
curl -s http://127.0.0.1:8090/v1/tools -H "X-API-KEY: foo" | jq '[.[].name | select(startswith("jira"))]'
216+
```
217+
218+
```json
219+
["jira/get_issue", "jira/search_issues", "jira/create_issue", "jira/list_projects", ...]
220+
```
221+
222+
Your AI assistant can now cross-reference GitHub PRs with Jira tickets through a single MCP connection.

mcp-server/spicepod.yaml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
version: v1
2+
kind: Spicepod
3+
name: mcp-server
4+
5+
runtime:
6+
task_history:
7+
captured_output: truncated
8+
auth:
9+
api_key:
10+
enabled: true
11+
keys:
12+
- foo:rw
13+
14+
# GitHub data accelerated in-memory — sub-millisecond SQL from any MCP client
15+
datasets:
16+
- from: github:github.com/spiceai/cookbook/issues
17+
name: github_issues
18+
description: GitHub issues — filterable by state, label, assignee, or milestone
19+
params:
20+
github_token: ${secrets:GITHUB_PERSONAL_ACCESS_TOKEN}
21+
github_query_mode: search
22+
time_column: updated_at
23+
acceleration:
24+
enabled: true
25+
refresh_data_window: 90d
26+
refresh_check_interval: 5m
27+
28+
- from: github:github.com/spiceai/cookbook/pulls
29+
name: github_pulls
30+
description: GitHub pull requests — open, merged, or closed, with review comments
31+
params:
32+
github_token: ${secrets:GITHUB_PERSONAL_ACCESS_TOKEN}
33+
github_query_mode: search
34+
github_include_comments: all
35+
time_column: updated_at
36+
acceleration:
37+
enabled: true
38+
refresh_data_window: 30d
39+
refresh_check_interval: 5m
40+
41+
- from: github:github.com/spiceai/cookbook/commits
42+
name: github_commits
43+
description: Recent commits with author, message, and SHA
44+
params:
45+
github_token: ${secrets:GITHUB_PERSONAL_ACCESS_TOKEN}
46+
acceleration:
47+
enabled: true
48+
refresh_sql: SELECT * FROM github_commits LIMIT 500
49+
50+
# MCP servers — proxied through Spice's unified /v1/mcp endpoint
51+
tools:
52+
# GitHub MCP server — write tools (create issues, comment, search code, etc.)
53+
- name: github
54+
from: mcp:npx
55+
description: GitHub tools — create and update issues, review PRs, search code and repositories
56+
params:
57+
mcp_args: -y @modelcontextprotocol/server-github
58+
env:
59+
GITHUB_PERSONAL_ACCESS_TOKEN: ${secrets:GITHUB_PERSONAL_ACCESS_TOKEN}

0 commit comments

Comments
 (0)