Skip to content

Commit daef48d

Browse files
dschwarz26claudergambee
authored
Implement MCP and SDK streaming messages (#114)
Indicate task progress, both when running SDK (optional) and when using MCP Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Robert Gambee <robert@futuresearch.ai>
1 parent 3411620 commit daef48d

36 files changed

Lines changed: 2027 additions & 727 deletions

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"name": "everyrow",
1212
"source": "./",
1313
"description": "Claude Code plugin for the everyrow SDK - AI-powered data processing utilities for transforming, deduping, merging, ranking, and screening dataframes",
14-
"version": "0.2.1"
14+
"version": "0.3.0"
1515
}
1616
]
1717
}

.claude-plugin/plugin.json

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,50 @@
11
{
22
"name": "everyrow",
33
"description": "Claude Code plugin for the everyrow SDK - AI-powered data processing utilities for transforming, deduping, merging, ranking, and screening dataframes",
4-
"version": "0.2.1",
4+
"version": "0.3.0",
55
"author": {
66
"name": "FutureSearch"
77
},
88
"repository": "https://github.com/futuresearch/everyrow-sdk",
99
"mcpServers": {
1010
"everyrow": {
11-
"command": "uvx",
12-
"args": ["everyrow-mcp"],
11+
"command": "${CLAUDE_PLUGIN_ROOT}/everyrow-mcp/.venv/bin/everyrow-mcp",
1312
"env": {
1413
"EVERYROW_API_KEY": "${EVERYROW_API_KEY}"
1514
}
1615
}
16+
},
17+
"hooks": {
18+
"PostToolUse": [
19+
{
20+
"matcher": "mcp__plugin_everyrow_everyrow__everyrow_results",
21+
"hooks": [
22+
{
23+
"type": "command",
24+
"command": "\"${CLAUDE_PLUGIN_ROOT}/everyrow-mcp/scripts/everyrow-track-results.sh\""
25+
}
26+
]
27+
}
28+
],
29+
"Stop": [
30+
{
31+
"hooks": [
32+
{
33+
"type": "command",
34+
"command": "\"${CLAUDE_PLUGIN_ROOT}/everyrow-mcp/scripts/everyrow-stop-guard.sh\""
35+
}
36+
]
37+
}
38+
],
39+
"SessionEnd": [
40+
{
41+
"hooks": [
42+
{
43+
"type": "command",
44+
"command": "rm -f ~/.everyrow/task.json"
45+
}
46+
]
47+
}
48+
]
1749
}
1850
}

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ EVERYROW_API_KEY=
44

55
# Optional: API base URL (defaults to https://everyrow.io/api/v0/)
66
# EVERYROW_API_URL=https://everyrow.io/api/v0/
7+
# Optional: App base URL (defaults to https://everyrow.io/)
8+
# EVERYROW_APP_URL=https://everyrow.io/

.github/workflows/ci.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,21 @@ jobs:
8686

8787
- name: Run tests
8888
run: uv run --directory everyrow-mcp pytest tests
89+
90+
shell-tests:
91+
name: shell-scripts
92+
runs-on: ubuntu-latest
93+
steps:
94+
- uses: actions/checkout@v4
95+
96+
- name: Install jq
97+
run: sudo apt-get install -y jq
98+
99+
- name: Run status line tests
100+
run: bash everyrow-mcp/tests/test_statusline.sh
101+
102+
- name: Run stop guard tests
103+
run: bash everyrow-mcp/tests/test_hook_stop_guard.sh
104+
105+
- name: Run results hook tests
106+
run: bash everyrow-mcp/tests/test_hook_results.sh

CITATION.cff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type: software
44
title: "everyrow"
55
abstract: "Screen, rank, dedupe, and merge dataframes using natural language. Run web agents to research every row."
66
license: MIT
7-
version: 0.2.1
7+
version: 0.3.0
88
date-released: 2026-01-26
99
repository-code: "https://github.com/futuresearch/everyrow-sdk"
1010
url: "https://everyrow.io"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ Built by [FutureSearch](https://futuresearch.ai). We kept running into the same
236236
author = {FutureSearch},
237237
title = {everyrow},
238238
url = {https://github.com/futuresearch/everyrow-sdk},
239-
version = {0.2.1},
239+
version = {0.3.0},
240240
year = {2026},
241241
license = {MIT}
242242
}

docs-site/scripts/check-links.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@
5252
"https://geminicli.com/docs/cli/skills/",
5353
"https://geminicli.com/docs/extensions/",
5454
"https://geminicli.com/docs/tools/mcp-server/",
55+
"https://github.com/anthropics/claude-code/issues/12667",
5556
"https://github.com/anthropics/claude-code/issues/20377",
5657
"https://github.com/futuresearch/everyrow-sdk",
5758
"https://github.com/futuresearch/everyrow-sdk/releases",
5859
"https://huggingface.co/datasets/fancyzhx/dbpedia_14",
5960
"https://hugovk.github.io/top-pypi-packages/",
61+
"https://jqlang.org/",
6062
"https://www.kaggle.com/code/rafaelpoyiadzi/active-learning-with-an-llm-oracle",
6163
}
6264

docs-site/src/utils/docs.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ export function getNavigation(): NavSection[] {
123123
{ slug: "installation", title: "Installation", href: "/" },
124124
{ slug: "getting-started", title: "Getting Started" },
125125
{ slug: "api-key", title: "API Key", href: "https://everyrow.io/api-key" },
126+
{ slug: "mcp-server", title: "MCP Server" },
126127
{ slug: "skills-vs-mcp", title: "Skills vs MCP" },
128+
{ slug: "progress-monitoring", title: "Progress Monitoring" },
127129
{ slug: "chaining-operations", title: "Chaining Operations" },
128130
{ slug: "github", title: "GitHub", href: "https://github.com/futuresearch/everyrow-sdk" },
129131
],
@@ -140,7 +142,17 @@ export function getNavigation(): NavSection[] {
140142
title: "Guides",
141143
href: "/guides",
142144
items: guides
143-
.filter((d) => !["getting-started", "chaining-operations", "installation", "skills-vs-mcp", "guides", "notebooks", "api"].includes(d.slug))
145+
.filter((d) => ![
146+
"getting-started",
147+
"chaining-operations",
148+
"installation",
149+
"progress-monitoring",
150+
"mcp-server",
151+
"skills-vs-mcp",
152+
"guides",
153+
"notebooks",
154+
"api",
155+
].includes(d.slug))
144156
.map((d) => ({ slug: d.slug, title: d.title })),
145157
},
146158
{

docs/installation.mdx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ Config file location:
115115

116116
[Choosing the right scope](https://code.claude.com/docs/en/mcp#choosing-the-right-scope)
117117

118+
You can optionally configure Claude Code to show a [progress bar](/docs/progress-monitoring#progress-bar) for long-running tasks.
119+
118120
</TabContent>
119121

120122
<TabContent agent="claude-code" type="plugin">
@@ -128,7 +130,9 @@ claude plugin install everyrow@futuresearch
128130

129131
This installs both the skill and MCP server together. You can toggle each on/off in Claude Code settings.
130132

131-
[Official Docs](https://code.claude.com/docs/en/discover-plugins#add-from-github)
133+
You can optionally configure Claude Code to show a [progress bar](/docs/progress-monitoring#progress-bar) for long-running tasks.
134+
135+
[Official Claude Code Plugin Docs](https://code.claude.com/docs/en/discover-plugins#add-from-github)
132136

133137
</TabContent>
134138

@@ -330,3 +334,9 @@ Config file location:
330334
</TabContent>
331335

332336
</InstallationTabs>
337+
338+
## Dependencies
339+
340+
The MCP server requires **uv** (if using `uvx`) or **pip** (if installed directly). The Python SDK requires **Python 3.12+**.
341+
342+
For the optional terminal progress bar, see the [jq dependency](/docs/progress-monitoring#status-line-progress-bar) in the progress monitoring guide.

docs/mcp-server.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: MCP Server
3+
description: Reference for all everyrow MCP server tools — async operations with progress polling and result retrieval.
4+
---
5+
6+
# MCP Server Reference
7+
8+
The everyrow MCP server exposes tools for AI-powered data processing. These tools are called directly by Claude Code, Codex CLI, and other MCP clients — no Python code is needed.
9+
10+
All operations use an async pattern: submit the task, poll for progress, then retrieve results. This allows long-running operations (1–10+ minutes) to work reliably with MCP clients.
11+
12+
## Operation Tools
13+
14+
### everyrow_screen
15+
16+
Filter rows in a CSV based on criteria that require judgment.
17+
18+
| Parameter | Type | Required | Description |
19+
|-----------|------|----------|-------------|
20+
| `task` | string | Yes | Screening criteria. Rows that meet the criteria pass. |
21+
| `input_csv` | string | Yes | Absolute path to input CSV. |
22+
| `response_schema` | object | No | JSON schema for custom fields. Default: `{passes: bool}`. |
23+
24+
Returns `task_id` and `session_url`. Call `everyrow_progress` to monitor.
25+
26+
### everyrow_rank
27+
28+
Score and sort rows by qualitative criteria.
29+
30+
| Parameter | Type | Required | Description |
31+
|-----------|------|----------|-------------|
32+
| `task` | string | Yes | What makes a row score higher or lower. |
33+
| `input_csv` | string | Yes | Absolute path to input CSV. |
34+
| `field_name` | string | Yes | Column name for the score. |
35+
| `field_type` | string | No | Score type: `float` (default), `int`, `str`, `bool`. |
36+
| `ascending_order` | bool | No | `true` = lowest first (default). |
37+
| `response_schema` | object | No | JSON schema for additional fields. |
38+
39+
Returns `task_id` and `session_url`. Call `everyrow_progress` to monitor.
40+
41+
### everyrow_dedupe
42+
43+
Remove semantic duplicates.
44+
45+
| Parameter | Type | Required | Description |
46+
|-----------|------|----------|-------------|
47+
| `equivalence_relation` | string | Yes | What makes two rows duplicates. |
48+
| `input_csv` | string | Yes | Absolute path to input CSV. |
49+
50+
Returns `task_id` and `session_url`. Call `everyrow_progress` to monitor.
51+
52+
### everyrow_merge
53+
54+
Join two CSVs using intelligent entity matching.
55+
56+
| Parameter | Type | Required | Description |
57+
|-----------|------|----------|-------------|
58+
| `task` | string | Yes | How to match rows between tables. |
59+
| `left_csv` | string | Yes | Absolute path to primary CSV. |
60+
| `right_csv` | string | Yes | Absolute path to secondary CSV. |
61+
| `merge_on_left` | string | No | Column in left table to match on. |
62+
| `merge_on_right` | string | No | Column in right table to match on. |
63+
| `use_web_search` | string | No | `auto` (default), `yes`, or `no`. |
64+
65+
Returns `task_id` and `session_url`. Call `everyrow_progress` to monitor.
66+
67+
### everyrow_agent
68+
69+
Run web research agents on each row.
70+
71+
| Parameter | Type | Required | Description |
72+
|-----------|------|----------|-------------|
73+
| `task` | string | Yes | Task for the agent to perform on each row. |
74+
| `input_csv` | string | Yes | Absolute path to input CSV. |
75+
| `response_schema` | object | No | JSON schema for structured output. Default: `{answer: str}`. |
76+
77+
Returns `task_id` and `session_url`. Call `everyrow_progress` to monitor.
78+
79+
## Progress and Results Tools
80+
81+
### everyrow_progress
82+
83+
Check progress of a running task. **Blocks for a few seconds** before returning.
84+
85+
| Parameter | Type | Required | Description |
86+
|-----------|------|----------|-------------|
87+
| `task_id` | string | Yes | The task ID from an operation tool. |
88+
89+
Returns status text with completion counts and elapsed time. Instructs the agent to call again immediately until the task completes or fails.
90+
91+
### everyrow_results
92+
93+
Retrieve results from a completed task and save to CSV.
94+
95+
| Parameter | Type | Required | Description |
96+
|-----------|------|----------|-------------|
97+
| `task_id` | string | Yes | The task ID of the completed task. |
98+
| `output_path` | string | Yes | Directory or full .csv path for output. |
99+
100+
Returns confirmation with row count and file path.
101+
102+
## Workflow
103+
104+
```
105+
1. everyrow_agent(task, input_csv)
106+
→ Returns task_id + session_url (~0.6s)
107+
108+
2. everyrow_progress(task_id)
109+
→ Blocks 12s, returns "Running: 5/50 complete, 8 running (15s elapsed)"
110+
→ Response says "call everyrow_progress again immediately"
111+
112+
3. everyrow_progress(task_id) (repeat)
113+
→ "Running: 23/50 complete, 5 running (45s elapsed)"
114+
115+
4. everyrow_progress(task_id) (final)
116+
→ "Completed: 49 succeeded, 1 failed (142s total)"
117+
118+
5. everyrow_results(task_id, output_path)
119+
→ "Saved 50 rows to /path/to/agent_companies.csv"
120+
```
121+
122+
The agent handles this loop automatically. You don't need to intervene.
123+
124+
## Custom Response Schemas
125+
126+
All tools that accept `response_schema` take a JSON schema object:
127+
128+
```json
129+
{
130+
"properties": {
131+
"annual_revenue": {
132+
"type": "integer",
133+
"description": "Annual revenue in USD"
134+
},
135+
"employee_count": {
136+
"type": "integer",
137+
"description": "Number of employees"
138+
}
139+
},
140+
"required": ["annual_revenue"]
141+
}
142+
```
143+
144+
Supported types: `string`, `integer`, `number`, `boolean`, `array`, `object`.
145+
146+
## Plugin
147+
148+
The Claude Code plugin (`.claude-plugin/plugin.json`) bundles:
149+
150+
1. MCP server, with all tools above
151+
2. Hooks, such as stop guard (prevents ending turn during operations), results notification (macOS), session cleanup
152+
3. Skill, to guide agents with quick SDK code generation for the Python SDK path
153+
154+
Install with:
155+
```bash
156+
claude plugin marketplace add futuresearch/everyrow-sdk
157+
claude plugin install everyrow@futuresearch
158+
```
159+
160+
See [Progress Monitoring](/docs/progress-monitoring) for status line setup and hook details.

0 commit comments

Comments
 (0)