@dataville/dataville-mcp 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -3
- package/dist/client.js +9 -1
- package/dist/sources.js +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server exposing Dataville's data source API as tools for MCP clients (Claude Desktop, Claude Code, etc.).
|
|
4
4
|
|
|
5
|
+
[Dataville](https://dataville.com) is a unified REST API over ten public datasets —
|
|
6
|
+
Wikipedia, arXiv, Project Gutenberg, US Census, USDA FoodData, Papers with Code,
|
|
7
|
+
SEC EDGAR, OpenAlex, PyPI, and Stack Exchange — behind one interface and one API
|
|
8
|
+
key, with CSV/Parquet export and SQL query support. This package lets an MCP
|
|
9
|
+
client search any of those sources as a tool call.
|
|
10
|
+
|
|
5
11
|
Requires a Dataville API key — get one from the [Dataville dashboard](https://app.dataville.com/api-keys).
|
|
6
12
|
|
|
7
13
|
## Tools
|
|
@@ -11,7 +17,32 @@ Requires a Dataville API key — get one from the [Dataville dashboard](https://
|
|
|
11
17
|
|
|
12
18
|
## Setup
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
This package is a local (stdio) MCP server: the client launches it on your
|
|
21
|
+
machine via `npx`. If you don't need it running locally, connecting to
|
|
22
|
+
Dataville's hosted endpoint instead takes one line and no install.
|
|
23
|
+
|
|
24
|
+
### Hosted, in one line (no install)
|
|
25
|
+
|
|
26
|
+
Dataville also serves MCP directly over HTTP, so a client can connect without
|
|
27
|
+
running anything locally — no Node, no config file, no restart:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
claude mcp add --transport http dataville https://api.dataville.com/mcp
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
That works with no credentials at all (anonymous limits). Add
|
|
34
|
+
`--header "Authorization: Bearer dataville_your_key_here"` for the full quota.
|
|
35
|
+
Other clients take the same URL; the app's Integrations page has the exact
|
|
36
|
+
snippet for each. Use the hosted endpoint unless you specifically want to pin a
|
|
37
|
+
version or work offline — the rest of this section covers that local setup.
|
|
38
|
+
|
|
39
|
+
### Prerequisites
|
|
40
|
+
|
|
41
|
+
- **Node.js** (LTS) installed — this is what runs `npx`. Without it the server
|
|
42
|
+
fails to start. Check with `node --version`.
|
|
43
|
+
- A **Dataville API key** — get one from https://app.dataville.com/api-keys.
|
|
44
|
+
|
|
45
|
+
The config block is the same everywhere; only *where* you put it differs:
|
|
15
46
|
|
|
16
47
|
```json
|
|
17
48
|
{
|
|
@@ -29,7 +60,36 @@ Add this to your MCP client config (Claude Code / Claude Desktop), with `DATAVIL
|
|
|
29
60
|
|
|
30
61
|
No install step needed — `npx` fetches and runs the package on demand.
|
|
31
62
|
|
|
32
|
-
|
|
63
|
+
### Claude Desktop
|
|
64
|
+
|
|
65
|
+
1. Open **Settings → Developer → Edit Config**. This opens `claude_desktop_config.json`:
|
|
66
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
67
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
68
|
+
2. Add the block above (merge into `mcpServers` if the file already has one),
|
|
69
|
+
with your real key.
|
|
70
|
+
3. **Fully quit and reopen** Claude Desktop — quit from the menu bar / system
|
|
71
|
+
tray, not just closing the window.
|
|
72
|
+
4. The dataville tools now appear under the tools icon in the chat box, and
|
|
73
|
+
Settings → Developer shows `dataville` running.
|
|
74
|
+
|
|
75
|
+
Note: the server appears as **tools**, not in the **Connectors** directory —
|
|
76
|
+
that directory only lists remote (hosted) connectors and will not find a local
|
|
77
|
+
server. Ask naturally ("get Apple's latest revenue from dataville") and the
|
|
78
|
+
client calls the tool.
|
|
79
|
+
|
|
80
|
+
### Claude Code
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
claude mcp add dataville -e DATAVILLE_API_KEY=dataville_your_key_here -- npx -y @dataville/dataville-mcp
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Restart the session so the tools load. Add `-s user` to make it available in
|
|
87
|
+
every project instead of just the current one.
|
|
88
|
+
|
|
89
|
+
### Configuration
|
|
90
|
+
|
|
91
|
+
`DATAVILLE_API_BASE_URL` is optional and defaults to `https://api.dataville.com`;
|
|
92
|
+
set it to `http://localhost:5000` to point at a local backend during development.
|
|
33
93
|
|
|
34
94
|
### Running from source
|
|
35
95
|
|
|
@@ -40,6 +100,22 @@ npm install
|
|
|
40
100
|
npm run build
|
|
41
101
|
```
|
|
42
102
|
|
|
103
|
+
## Check that it works
|
|
104
|
+
|
|
105
|
+
Ask your client one of these. Each answer is checkable on purpose — a model that
|
|
106
|
+
skipped the tool and answered from memory sounds just as confident, so a reply
|
|
107
|
+
on its own proves nothing.
|
|
108
|
+
|
|
109
|
+
| Ask | What proves it |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `Which data sources does Dataville have?` | Calls `list_dataville_sources` and names all eleven. |
|
|
112
|
+
| `Using Dataville, what is the latest version of the requests package on PyPI?` | A version you can confirm on pypi.org — and it moves, so it can't come from memory. |
|
|
113
|
+
| `Using Dataville, get the latest SEC filing for AAPL and its revenue.` | A form type, filing date, revenue figure, and a sec.gov link to open. |
|
|
114
|
+
| `Using Dataville, how much protein is in 100g of uncooked quinoa?` | The exact USDA figure, 14.1 g per 100 g. |
|
|
115
|
+
|
|
116
|
+
Clients show when a tool ran. If you don't see that, say "use dataville" in the
|
|
117
|
+
prompt to make it explicit, and check the answer against the source.
|
|
118
|
+
|
|
43
119
|
## Development
|
|
44
120
|
|
|
45
121
|
```bash
|
|
@@ -52,4 +128,12 @@ npm run build # tsc
|
|
|
52
128
|
|
|
53
129
|
Publishes run from CI via npm trusted publishing (OIDC) — no tokens are stored.
|
|
54
130
|
To cut a release: bump the version, update `CHANGELOG.md`, then publish a GitHub
|
|
55
|
-
Release for the new tag. The `Publish` workflow builds, tests, and publishes to npm
|
|
131
|
+
Release for the new tag. The `Publish` workflow builds, tests, and publishes to npm,
|
|
132
|
+
then publishes `server.json` to the [MCP Registry](https://registry.modelcontextprotocol.io)
|
|
133
|
+
(its version is set from `package.json`, so don't bump it by hand).
|
|
134
|
+
|
|
135
|
+
The registry name `com.dataville/dataville-mcp` is authorized by a DNS TXT record
|
|
136
|
+
on the `dataville.com` apex (`v=MCPv1; k=ed25519; p=<public key>`), checked
|
|
137
|
+
against the Ed25519 private key in the `MCP_PRIVATE_KEY` repo secret (hex). If the
|
|
138
|
+
`mcp-registry` job fails at login, check that record and secret, then re-run just
|
|
139
|
+
that job.
|
package/dist/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const DEFAULT_BASE_URL = "https://api.dataville.com";
|
|
2
2
|
// Keep in sync with package.json version (enforced by a test).
|
|
3
|
-
export const VERSION = "0.1.
|
|
3
|
+
export const VERSION = "0.1.5";
|
|
4
4
|
const USER_AGENT = `dataville-mcp/${VERSION}`;
|
|
5
5
|
export class DatavilleApiError extends Error {
|
|
6
6
|
status;
|
|
@@ -35,6 +35,14 @@ function getConfig() {
|
|
|
35
35
|
}
|
|
36
36
|
export async function searchDataSource(source, keywords, params) {
|
|
37
37
|
const { apiKey, baseUrl } = getConfig();
|
|
38
|
+
// encodeURIComponent leaves "." alone, and URL resolution collapses a "." or
|
|
39
|
+
// ".." segment — so source ".." would send the user's key to /<keywords>
|
|
40
|
+
// instead of a data route.
|
|
41
|
+
for (const [name, value] of [["source name", source], ["search term", keywords]]) {
|
|
42
|
+
if (value === "." || value === "..") {
|
|
43
|
+
throw new Error(`"${value}" is not a valid ${name}. Use list_dataville_sources to see valid source names.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
38
46
|
const url = new URL(`/${encodeURIComponent(source)}/${encodeURIComponent(keywords)}`, baseUrl);
|
|
39
47
|
if (params) {
|
|
40
48
|
for (const [key, value] of Object.entries(params)) {
|
package/dist/sources.js
CHANGED
|
@@ -13,5 +13,5 @@ export const DATAVILLE_SOURCES = [
|
|
|
13
13
|
{ name: "openalex", description: "OpenAlex scholarly works" },
|
|
14
14
|
{ name: "pypi", description: "PyPI package metadata" },
|
|
15
15
|
{ name: "stackexchange", description: "Stack Exchange Q&A" },
|
|
16
|
-
{ name: "news", description: "
|
|
16
|
+
{ name: "news", description: "Front-page news headlines from a historical archive (not live/current news)" },
|
|
17
17
|
];
|
package/package.json
CHANGED