govql-mcp-server 0.1.0__tar.gz

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.
Files changed (29) hide show
  1. govql_mcp_server-0.1.0/.env +8 -0
  2. govql_mcp_server-0.1.0/.gitignore +9 -0
  3. govql_mcp_server-0.1.0/.python-version +1 -0
  4. govql_mcp_server-0.1.0/CHANGELOG.md +25 -0
  5. govql_mcp_server-0.1.0/CONTRIBUTING.md +51 -0
  6. govql_mcp_server-0.1.0/LICENSE +21 -0
  7. govql_mcp_server-0.1.0/PKG-INFO +137 -0
  8. govql_mcp_server-0.1.0/README.md +116 -0
  9. govql_mcp_server-0.1.0/RELEASE.md +242 -0
  10. govql_mcp_server-0.1.0/docs/design.md +93 -0
  11. govql_mcp_server-0.1.0/pyproject.toml +47 -0
  12. govql_mcp_server-0.1.0/src/govql_mcp_server/__init__.py +3 -0
  13. govql_mcp_server-0.1.0/src/govql_mcp_server/__main__.py +17 -0
  14. govql_mcp_server-0.1.0/src/govql_mcp_server/graphql_client.py +86 -0
  15. govql_mcp_server-0.1.0/src/govql_mcp_server/logger.py +14 -0
  16. govql_mcp_server-0.1.0/src/govql_mcp_server/server.py +17 -0
  17. govql_mcp_server-0.1.0/src/govql_mcp_server/tools/__init__.py +0 -0
  18. govql_mcp_server-0.1.0/src/govql_mcp_server/tools/_discovery_shared.py +47 -0
  19. govql_mcp_server-0.1.0/src/govql_mcp_server/tools/describe_type.py +100 -0
  20. govql_mcp_server-0.1.0/src/govql_mcp_server/tools/list_types.py +68 -0
  21. govql_mcp_server-0.1.0/src/govql_mcp_server/tools/passthrough.py +112 -0
  22. govql_mcp_server-0.1.0/tests/__init__.py +0 -0
  23. govql_mcp_server-0.1.0/tests/conftest.py +67 -0
  24. govql_mcp_server-0.1.0/tests/test_describe_type.py +93 -0
  25. govql_mcp_server-0.1.0/tests/test_graphql_client.py +91 -0
  26. govql_mcp_server-0.1.0/tests/test_list_types.py +62 -0
  27. govql_mcp_server-0.1.0/tests/test_no_stdout.py +59 -0
  28. govql_mcp_server-0.1.0/tests/test_passthrough.py +88 -0
  29. govql_mcp_server-0.1.0/uv.lock +1809 -0
@@ -0,0 +1,8 @@
1
+ #/-------------------[DOTENV_PUBLIC_KEY]--------------------/
2
+ #/ public-key encryption for .env files /
3
+ #/ [how it works](https://dotenvx.com/encryption) /
4
+ #/----------------------------------------------------------/
5
+ DOTENV_PUBLIC_KEY="02554c3f8b0af44845544039073d017590bcc4495a6a8832f9d50ee8d9cc606fdd"
6
+
7
+ # .env
8
+ UV_PUBLISH_TOKEN="encrypted:BDQbQySFzQ3YqYAmJRx2rDujwXL34EYQ/r8CX4rbvlPrzy/s7NTdnCOl/hNgYmKqTyEunMyWdIiRpeV5vRmNSCyR39lVD+LvAm2pUz1PMjQ6Y7ja31SA89AJCe7fpIvmxxsk4hezjXqB5+thrzS5MiNLzBIZJb7/x+ozzQ8tGfmACY2Sp19mNZaS0S4JCJYNSdv/leS2mP98Uh3bpCpXpqYfCWwrlcS5qBNkG/jXnk9LM40AjlK5RddWVLWwIShIAv32mQX5dMLaymdvM7wIz2RDnvPWKpS6t6g6yuS9ZDpbDvgb26NFW1FFAWQEM4AzAWEGw9bWvAWb2YK7YvQtuE3JuA6sVQS/XcM4Z6tun9wQXWds"
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ dist/
3
+ build/
4
+ __pycache__/
5
+ *.egg-info/
6
+ .pytest_cache/
7
+ test-reports/
8
+
9
+ .env.keys
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to `govql-mcp-server` are documented in this file.
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.1.0] — 2026-05-28
8
+
9
+ Initial release.
10
+
11
+ ### Added
12
+
13
+ - `execute_graphql` tool — passthrough that runs any GraphQL query against
14
+ the GovQL endpoint and returns the result along with a `last_ingest`
15
+ freshness timestamp.
16
+ - `list_types` tool — returns the names and kinds of every type in the
17
+ GovQL schema, with an optional case-insensitive `kind` filter.
18
+ - `describe_type` tool — returns one GraphQL type's full description
19
+ (fields, arg signatures, input fields, enum values) by name.
20
+ - stdio transport (works with Claude Desktop, Claude Code, Cursor, and any
21
+ other MCP-compatible client that supports stdio servers).
22
+ - Configuration via `GOVQL_ENDPOINT`, `GOVQL_TIMEOUT_MS`, and `LOG_LEVEL`
23
+ environment variables (all optional — defaults point at the public API).
24
+ - Full test suite (23 tests) using FastMCP's in-memory client, including a
25
+ guardrail test that fails if any module writes to stdout.
@@ -0,0 +1,51 @@
1
+ # Contributing to govql-mcp-server
2
+
3
+ This is the Python sub-project of the [GovQL monorepo](https://github.com/govql/govql).
4
+ The rest of the repo (under `us-congress/`) is JavaScript; this package is
5
+ deliberately self-contained.
6
+
7
+ ## Quick start
8
+
9
+ You'll need [uv](https://github.com/astral-sh/uv) (the Python package
10
+ manager). Install it with the one-liner from its README, then:
11
+
12
+ ```bash
13
+ uv sync # install deps into a local .venv
14
+ uv run pytest # run the test suite
15
+ uv build # build wheel + sdist for publishing
16
+ ```
17
+
18
+ uv reads `.python-version` (currently `3.14`) to pick the interpreter; if
19
+ you don't have it installed it will fetch it automatically.
20
+
21
+ ## Layout
22
+
23
+ - `src/govql_mcp_server/` — the package
24
+ - `server.py` — FastMCP instance; importing the tools modules registers them
25
+ - `graphql_client.py` — thin httpx wrapper around the GovQL endpoint
26
+ - `tools/` — one file per tool
27
+ - `logger.py` — stderr-only logging (stdout is the MCP transport — see
28
+ "Hard rule" below)
29
+ - `tests/` — pytest suite using FastMCP's in-memory client
30
+ - `docs/design.md` — why the project exists, what's in / out of scope, roadmap
31
+
32
+ ## Hard rule: never write to stdout
33
+
34
+ stdout is the MCP transport. Any stray `print()` corrupts the JSON-RPC
35
+ framing and silently breaks every client. Use the logger
36
+ (`from .logger import logger`). The test suite includes
37
+ `tests/test_no_stdout.py` which fails the build if anything in the package
38
+ writes to stdout.
39
+
40
+ ## Adding a new tool
41
+
42
+ Each tool gets its own file in `src/govql_mcp_server/tools/` and its own
43
+ test file in `tests/`. Pattern:
44
+
45
+ 1. Create `tools/your_tool.py`. Import `mcp` from `..server` and decorate
46
+ an async function with `@mcp.tool`.
47
+ 2. Add the module to the import line at the bottom of `server.py` so the
48
+ decorator runs at startup.
49
+ 3. Add `tests/test_your_tool.py` using the in-memory `client` fixture from
50
+ `conftest.py`.
51
+ 4. Update `README.md`'s tools table and `CHANGELOG.md`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GovQL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: govql-mcp-server
3
+ Version: 0.1.0
4
+ Summary: MCP server for GovQL — query US Congressional data via GraphQL from any MCP client.
5
+ Project-URL: Homepage, https://govql.us
6
+ Project-URL: Repository, https://github.com/govql/govql
7
+ Project-URL: Issues, https://github.com/govql/govql/issues
8
+ Author: GovQL
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,congress,government,graphql,mcp,model-context-protocol
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: fastmcp>=3.3.0
19
+ Requires-Dist: httpx>=0.27.0
20
+ Description-Content-Type: text/markdown
21
+
22
+ # govql-mcp-server
23
+
24
+ An MCP (Model Context Protocol) server for [GovQL](https://govql.us) — gives
25
+ AI clients like Claude Desktop, Claude Code, and Cursor direct access to the
26
+ US Congressional GraphQL API at [api.govql.us/graphql](https://api.govql.us/graphql)
27
+ without bespoke HTTP wiring.
28
+
29
+ For the design rationale (why FastMCP-Python, the passthrough+curated philosophy,
30
+ roadmap through v0.4), see
31
+ [design.md](https://github.com/govql/govql/blob/main/mcp-server/docs/design.md).
32
+
33
+ ## What you can do with it
34
+
35
+ Ask an agent questions like:
36
+
37
+ - *"How did Vermont's two senators vote on the most recent nomination?"*
38
+ - *"Which legislators in the 118th Congress switched parties during their service?"*
39
+ - *"Compare Senator Sanders' voting record to Senator Murkowski's on cloture votes
40
+ in the most recent Congress."*
41
+
42
+ The agent picks the right tool, writes the GraphQL query against the live
43
+ schema, and parses the response — no manual API wrangling.
44
+
45
+ ## Install
46
+
47
+ The server runs as a per-client subprocess over stdio. Pick your client:
48
+
49
+ ### Claude Desktop
50
+
51
+ Edit `claude_desktop_config.json` (Settings → Developer → Edit Config):
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "govql": {
57
+ "command": "uvx",
58
+ "args": ["govql-mcp-server"]
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ Restart Claude Desktop. The `govql` tools appear in the tools panel.
65
+
66
+ ### Claude Code
67
+
68
+ Add to `.mcp.json` in your project (or `~/.mcp.json` for global):
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "govql": {
74
+ "command": "uvx",
75
+ "args": ["govql-mcp-server"]
76
+ }
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### Cursor
82
+
83
+ Settings → MCP → Add Server. Use the same `command` / `args` as above.
84
+
85
+ ### Other clients
86
+
87
+ Any MCP-compatible client that supports stdio servers will work. The command
88
+ is `uvx govql-mcp-server` with no required arguments.
89
+
90
+ ## Tools
91
+
92
+ | Tool | Purpose |
93
+ |---|---|
94
+ | `execute_graphql` | Run any GraphQL query against the GovQL endpoint. Returns the result plus an `last_ingest` timestamp so the agent can reason about data freshness. |
95
+ | `list_types` | Returns the names and kinds of every type in the GovQL schema. Optional `kind` filter (`"OBJECT"`, `"INPUT_OBJECT"`, `"ENUM"`, etc.) to narrow further. Start here when you don't know what's queryable. |
96
+ | `describe_type` | Returns one type's full details — fields, arg signatures, input fields, enum values. Call after `list_types` to learn the shape of a specific type before writing a query. |
97
+
98
+ ## Configuration
99
+
100
+ All env vars are optional — the package is zero-config for end users.
101
+
102
+ | Env var | Default | Purpose |
103
+ |---|---|---|
104
+ | `GOVQL_ENDPOINT` | `https://api.govql.us/graphql` | Endpoint to query. Override to point at a local dev stack. |
105
+ | `GOVQL_TIMEOUT_MS` | `30000` | Per-request HTTP timeout. |
106
+ | `LOG_LEVEL` | `INFO` | Logging level. Logs go to stderr only (stdout is reserved for the MCP transport). |
107
+
108
+ ## Limits (enforced by the upstream API)
109
+
110
+ - Max query depth: 10
111
+ - Max query complexity: ~10 billion points (`first: N` multiplies child cost
112
+ by N — keep page sizes reasonable on deeply nested queries)
113
+ - Rate limit: 100 requests / 60 s per source IP
114
+
115
+ A depth or complexity violation surfaces as a GraphQL `errors` entry in the
116
+ tool response so the agent can adjust and retry.
117
+
118
+ ## Data freshness
119
+
120
+ Every `execute_graphql` response includes a `last_ingest` ISO timestamp.
121
+ Vote data refreshes hourly; legislator data refreshes daily.
122
+
123
+ ## Status
124
+
125
+ Version 0.1.0 ships three foundational tools: a GraphQL passthrough
126
+ (`execute_graphql`) and two narrow schema-discovery tools (`list_types`,
127
+ `describe_type`). Curated higher-level tools (`find_legislator`,
128
+ `get_voting_record`, `compare_voters`, etc.) are planned for subsequent
129
+ releases — see
130
+ [design.md](https://github.com/govql/govql/blob/main/mcp-server/docs/design.md)
131
+ for the roadmap.
132
+
133
+ ## Links
134
+
135
+ - [GovQL project site](https://govql.us)
136
+ - [GraphQL API](https://api.govql.us/graphql)
137
+ - [Source / issues](https://github.com/govql/govql)
@@ -0,0 +1,116 @@
1
+ # govql-mcp-server
2
+
3
+ An MCP (Model Context Protocol) server for [GovQL](https://govql.us) — gives
4
+ AI clients like Claude Desktop, Claude Code, and Cursor direct access to the
5
+ US Congressional GraphQL API at [api.govql.us/graphql](https://api.govql.us/graphql)
6
+ without bespoke HTTP wiring.
7
+
8
+ For the design rationale (why FastMCP-Python, the passthrough+curated philosophy,
9
+ roadmap through v0.4), see
10
+ [design.md](https://github.com/govql/govql/blob/main/mcp-server/docs/design.md).
11
+
12
+ ## What you can do with it
13
+
14
+ Ask an agent questions like:
15
+
16
+ - *"How did Vermont's two senators vote on the most recent nomination?"*
17
+ - *"Which legislators in the 118th Congress switched parties during their service?"*
18
+ - *"Compare Senator Sanders' voting record to Senator Murkowski's on cloture votes
19
+ in the most recent Congress."*
20
+
21
+ The agent picks the right tool, writes the GraphQL query against the live
22
+ schema, and parses the response — no manual API wrangling.
23
+
24
+ ## Install
25
+
26
+ The server runs as a per-client subprocess over stdio. Pick your client:
27
+
28
+ ### Claude Desktop
29
+
30
+ Edit `claude_desktop_config.json` (Settings → Developer → Edit Config):
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "govql": {
36
+ "command": "uvx",
37
+ "args": ["govql-mcp-server"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ Restart Claude Desktop. The `govql` tools appear in the tools panel.
44
+
45
+ ### Claude Code
46
+
47
+ Add to `.mcp.json` in your project (or `~/.mcp.json` for global):
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "govql": {
53
+ "command": "uvx",
54
+ "args": ["govql-mcp-server"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### Cursor
61
+
62
+ Settings → MCP → Add Server. Use the same `command` / `args` as above.
63
+
64
+ ### Other clients
65
+
66
+ Any MCP-compatible client that supports stdio servers will work. The command
67
+ is `uvx govql-mcp-server` with no required arguments.
68
+
69
+ ## Tools
70
+
71
+ | Tool | Purpose |
72
+ |---|---|
73
+ | `execute_graphql` | Run any GraphQL query against the GovQL endpoint. Returns the result plus an `last_ingest` timestamp so the agent can reason about data freshness. |
74
+ | `list_types` | Returns the names and kinds of every type in the GovQL schema. Optional `kind` filter (`"OBJECT"`, `"INPUT_OBJECT"`, `"ENUM"`, etc.) to narrow further. Start here when you don't know what's queryable. |
75
+ | `describe_type` | Returns one type's full details — fields, arg signatures, input fields, enum values. Call after `list_types` to learn the shape of a specific type before writing a query. |
76
+
77
+ ## Configuration
78
+
79
+ All env vars are optional — the package is zero-config for end users.
80
+
81
+ | Env var | Default | Purpose |
82
+ |---|---|---|
83
+ | `GOVQL_ENDPOINT` | `https://api.govql.us/graphql` | Endpoint to query. Override to point at a local dev stack. |
84
+ | `GOVQL_TIMEOUT_MS` | `30000` | Per-request HTTP timeout. |
85
+ | `LOG_LEVEL` | `INFO` | Logging level. Logs go to stderr only (stdout is reserved for the MCP transport). |
86
+
87
+ ## Limits (enforced by the upstream API)
88
+
89
+ - Max query depth: 10
90
+ - Max query complexity: ~10 billion points (`first: N` multiplies child cost
91
+ by N — keep page sizes reasonable on deeply nested queries)
92
+ - Rate limit: 100 requests / 60 s per source IP
93
+
94
+ A depth or complexity violation surfaces as a GraphQL `errors` entry in the
95
+ tool response so the agent can adjust and retry.
96
+
97
+ ## Data freshness
98
+
99
+ Every `execute_graphql` response includes a `last_ingest` ISO timestamp.
100
+ Vote data refreshes hourly; legislator data refreshes daily.
101
+
102
+ ## Status
103
+
104
+ Version 0.1.0 ships three foundational tools: a GraphQL passthrough
105
+ (`execute_graphql`) and two narrow schema-discovery tools (`list_types`,
106
+ `describe_type`). Curated higher-level tools (`find_legislator`,
107
+ `get_voting_record`, `compare_voters`, etc.) are planned for subsequent
108
+ releases — see
109
+ [design.md](https://github.com/govql/govql/blob/main/mcp-server/docs/design.md)
110
+ for the roadmap.
111
+
112
+ ## Links
113
+
114
+ - [GovQL project site](https://govql.us)
115
+ - [GraphQL API](https://api.govql.us/graphql)
116
+ - [Source / issues](https://github.com/govql/govql)
@@ -0,0 +1,242 @@
1
+ # Releasing govql-mcp-server
2
+
3
+ The steps to ship a new version. Written for v0.1.0 but reusable for subsequent
4
+ releases — just substitute the version number throughout.
5
+
6
+ All commands assume you're in `mcp-server/` unless noted otherwise.
7
+
8
+ ---
9
+
10
+ ## 0. Prerequisites (one-time setup)
11
+
12
+ Skip this section if you've published before.
13
+
14
+ ### PyPI account + token
15
+
16
+ 1. Create an account at [pypi.org](https://pypi.org/account/register/) (and
17
+ verify your email).
18
+ 2. Enable 2FA — PyPI requires it for publishers.
19
+ 3. Create a **scoped API token**:
20
+ [pypi.org/manage/account/token/](https://pypi.org/manage/account/token/).
21
+ First release: scope to "Entire account" (the package doesn't exist yet so
22
+ you can't scope to it). After v0.1.0 is up, **revoke that token and create
23
+ a new one scoped to the `govql-mcp-server` project only.**
24
+ 4. Store the token somewhere you'll find it again. For local releases, the
25
+ easiest path is to export it before publishing:
26
+ ```bash
27
+ export UV_PUBLISH_TOKEN="pypi-AgEI..."
28
+ ```
29
+ If you'd rather not type this every time, drop it in your shell's
30
+ per-project environment (e.g. `.env` with dotenvx, or direnv).
31
+
32
+ ### MCP registry (mcp.so) account
33
+
34
+ You'll need a free account at [mcp.so](https://mcp.so) to submit the listing
35
+ in step 4. Sign up now if you haven't.
36
+
37
+ ---
38
+
39
+ ## 1. Pre-flight checks
40
+
41
+ Run from `mcp-server/`. All of these should pass before you go further.
42
+
43
+ ```bash
44
+ # Tests green
45
+ uv run pytest
46
+
47
+ # Build artifacts clean (no stale files from a previous build)
48
+ rm -rf dist/
49
+ uv build
50
+
51
+ # Wheel contents look right — should only contain govql_mcp_server/ and a dist-info
52
+ unzip -l dist/govql_mcp_server-0.1.0-py3-none-any.whl
53
+
54
+ # Sdist contents look right — full source tree including tests/, docs/, CHANGELOG
55
+ tar tzf dist/govql_mcp_server-0.1.0.tar.gz
56
+ ```
57
+
58
+ Quick checklist of things to eyeball:
59
+
60
+ - `CHANGELOG.md` has an entry for the version you're about to release
61
+ - `pyproject.toml`'s `version` matches that CHANGELOG entry
62
+ - `README.md` describes the *current* tool set (no "coming soon" wording)
63
+ - No half-finished branches or commented-out code on the release commit
64
+
65
+ ---
66
+
67
+ ## 2. Real MCP client test (gate before publishing)
68
+
69
+ This is the only test that proves "an actual agent can use this." Don't
70
+ publish without it.
71
+
72
+ Pick a client. **Claude Desktop** is recommended for the first release because
73
+ it makes the tool calls visible in the UI.
74
+
75
+ ### Wire up the *local* build (not the PyPI version)
76
+
77
+ ```bash
78
+ # Confirm the local entry point works
79
+ GOVQL_ENDPOINT=https://api.govql.us/graphql uv run govql-mcp-server
80
+ # (Ctrl-C to stop — you're just confirming it starts cleanly. No prompt means it's
81
+ # waiting on stdin for MCP messages, which is correct.)
82
+ ```
83
+
84
+ In Claude Desktop, edit `claude_desktop_config.json` (Settings → Developer →
85
+ Edit Config) and add an entry pointing at this checkout:
86
+
87
+ ```json
88
+ {
89
+ "mcpServers": {
90
+ "govql-local": {
91
+ "command": "uv",
92
+ "args": [
93
+ "--directory",
94
+ "/home/astout5/govql/mcp-server",
95
+ "run",
96
+ "govql-mcp-server"
97
+ ]
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ Restart Claude Desktop. Confirm `govql-local` shows up in the tools panel
104
+ with `execute_graphql`, `list_types`, and `describe_type` listed.
105
+
106
+ ### The test prompt
107
+
108
+ Ask:
109
+
110
+ > *How did Vermont's two senators vote on the most recent nomination?*
111
+
112
+ Expected behavior:
113
+
114
+ 1. The agent calls `list_types` / `describe_type` as needed (or already
115
+ knows the schema from a prior session).
116
+ 2. It writes a query against `allVotes` + `votePositions` filtering for
117
+ Vermont senators and the latest nomination.
118
+ 3. It returns a concise answer naming both senators and their positions.
119
+
120
+ If anything is off (the agent gets confused, the query fails, the answer is
121
+ wrong), fix it before publishing — the issue is almost certainly in the
122
+ `execute_graphql` docstring in
123
+ `src/govql_mcp_server/tools/passthrough.py`, which is the agent's primary
124
+ guide.
125
+
126
+ ### Capture the transcript
127
+
128
+ Once it works, copy the transcript into `README.md` under a "Try it" or
129
+ "Example" section so PyPI visitors see a concrete demo on the project page.
130
+ Commit the README change before publishing.
131
+
132
+ ### Remove the local config
133
+
134
+ After the test, remove the `govql-local` entry from
135
+ `claude_desktop_config.json` so you don't have two GovQL servers competing
136
+ once the real one is installed.
137
+
138
+ ---
139
+
140
+ ## 3. Publish to PyPI
141
+
142
+ ```bash
143
+ # 1. Re-build with the final README/CHANGELOG/version in place.
144
+ rm -rf dist/
145
+ uv build
146
+
147
+ # 2. Publish. UV_PUBLISH_TOKEN must be set (see Prerequisites).
148
+ uv publish
149
+
150
+ # 3. Verify it's live by installing it in a throwaway location.
151
+ # Should print version 0.1.0 and exit cleanly (subprocess waits on stdin
152
+ # for MCP messages; just confirm it starts).
153
+ uvx --refresh govql-mcp-server --help 2>&1 | head -5
154
+ ```
155
+
156
+ If the publish fails on `name already exists`: someone took the name. Pick
157
+ one of the fallbacks from the original plan (`govql`, `mcp-govql`,
158
+ `govql-mcp`), update `pyproject.toml` + every README install snippet to match,
159
+ re-run pre-flight, and try again.
160
+
161
+ ---
162
+
163
+ ## 4. Tag the release in git
164
+
165
+ From the **repo root** (not `mcp-server/`):
166
+
167
+ ```bash
168
+ cd /home/astout5/govql
169
+
170
+ # Sanity: the working tree should be clean and on the merge commit that includes the release.
171
+ git status
172
+ git log -1 --oneline
173
+
174
+ # Tag and push.
175
+ git tag -a govql-mcp-server-v0.1.0 -m "govql-mcp-server v0.1.0"
176
+ git push origin govql-mcp-server-v0.1.0
177
+ ```
178
+
179
+ The tag is namespaced with `govql-mcp-server-` so it doesn't collide with
180
+ future tags for other sub-projects (e.g. a hypothetical
181
+ `us-congress-api-v1.0.0`).
182
+
183
+ ---
184
+
185
+ ## 5. Submit to the MCP registry (mcp.so)
186
+
187
+ 1. Log into [mcp.so](https://mcp.so).
188
+ 2. Click "Submit MCP Server" (or whatever the current entry point is called).
189
+ 3. Fill in:
190
+ - **Name:** `govql`
191
+ - **Description:** "MCP server for GovQL — query US Congressional voting
192
+ data (legislators, roll-call votes, etc.) via GraphQL from any MCP
193
+ client."
194
+ - **GitHub URL:** `https://github.com/govql/govql/tree/main/mcp-server`
195
+ - **Install / config snippet** (JSON):
196
+ ```json
197
+ {
198
+ "mcpServers": {
199
+ "govql": {
200
+ "command": "uvx",
201
+ "args": ["govql-mcp-server"]
202
+ }
203
+ }
204
+ }
205
+ ```
206
+ 4. Submit and wait for moderation (typically a few hours to a few days).
207
+ 5. Once approved, copy the registry URL into the next CHANGELOG entry under
208
+ the relevant version so future contributors can find it.
209
+
210
+ ---
211
+
212
+ ## 6. Post-release sanity checks
213
+
214
+ About 5 minutes after `uv publish`:
215
+
216
+ ```bash
217
+ # Confirm the package is visible on PyPI.
218
+ curl -sS https://pypi.org/pypi/govql-mcp-server/json | jq '.info.version, .info.home_page'
219
+
220
+ # Confirm a fresh install from PyPI works (use --refresh to bypass uv's cache).
221
+ uvx --refresh --from govql-mcp-server==0.1.0 govql-mcp-server --help 2>&1 | head -5
222
+ ```
223
+
224
+ Then in Claude Desktop, replace the local-build config with the PyPI version
225
+ (the snippet in `README.md`) and re-run the Vermont prompt to confirm the
226
+ published artifact behaves identically to the local build.
227
+
228
+ ---
229
+
230
+ ## 7. Graceful-exit check
231
+
232
+ Before stopping work, confirm every item below — this is the discipline that
233
+ makes a paused-mid-project portfolio piece still look intentional:
234
+
235
+ - [ ] Latest version is on PyPI
236
+ - [ ] Matching git tag is pushed
237
+ - [ ] `CHANGELOG.md` has the entry
238
+ - [ ] `README.md` accurately describes the *current* tool set
239
+ - [ ] No half-merged branches, no commented-out scaffolding, no TODO
240
+ comments pointing at the next version
241
+ - [ ] MCP-server Docusaurus page reflects the current tool set
242
+ - [ ] MCP registry listing submitted (or approved)