wikicitation-mcp 0.3.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.
@@ -0,0 +1,62 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python 3.11
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.11"
20
+
21
+ - name: Install uv
22
+ run: pip install uv
23
+
24
+ - name: Install dependencies
25
+ run: uv sync --dev
26
+
27
+ - name: Run unit tests (no R required)
28
+ run: uv run pytest -k "not bridge and not integration" -v
29
+
30
+ test-with-r:
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - name: Set up Python 3.11
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: "3.11"
40
+
41
+ - name: Set up R
42
+ uses: r-lib/actions/setup-r@v2
43
+ with:
44
+ r-version: "4.3"
45
+
46
+ - name: Install wikilite and dependencies
47
+ run: |
48
+ Rscript -e "install.packages('remotes', repos='https://cloud.r-project.org')"
49
+ Rscript -e "remotes::install_github('jsobel1/wikilite')"
50
+
51
+ - name: Install uv
52
+ run: pip install uv
53
+
54
+ - name: Install Python dependencies
55
+ run: uv sync --dev
56
+
57
+ - name: Run unit + bridge tests
58
+ run: uv run pytest -k "not integration" -v
59
+
60
+ - name: Run integration tests
61
+ run: uv run pytest --run-integration -v
62
+ continue-on-error: true # network calls may flake; don't block CI
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .pytest_cache/
5
+ .venv/
6
+ venv/
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ .env
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to `wikicitation-mcp` are documented here.
4
+ This project adheres to [Semantic Versioning](https://semver.org/).
5
+
6
+ ---
7
+
8
+ ## [0.2.0] — 2026-04-25
9
+
10
+ ### Added
11
+ - Streamable-HTTP transport mode for registration with the claude.ai web interface
12
+ - `uvx wikicitation-mcp` entry point for pip-installable deployment
13
+ - `annotate_doi_list_cross_ref` batch annotation with CrossRef polite-pool support
14
+ - `get_sci_score` corpus-wide quality scoring (proportion of templates with a DOI)
15
+ - Static and interactive visualisation tools (PNG base64 + self-contained HTML)
16
+ - pytest suite: unit tests (mocked subprocess), bridge tests (real Rscript),
17
+ and integration tests (live MediaWiki API, auto-skipped when wikilite absent)
18
+
19
+ ### Changed
20
+ - Migrated R backend from `WikiCitationHistoRy` to `wikilite`
21
+ - Renamed server from `WikiCitationHistoRy-mcp` to `wikicitation-mcp`
22
+ - R bridge now uses a fresh `Rscript` subprocess per call (eliminates shared
23
+ session state and memory leaks; adds ~0.3 s per-call overhead)
24
+ - Error boundaries: R-level exceptions are now propagated as descriptive
25
+ Python `RuntimeError` rather than raw stderr output
26
+
27
+ ### Fixed
28
+ - `get_top_cited_papers`: resolved `pkg.env not found` error on Windows
29
+ - Auto-detection of `Rscript` on Windows when not in `PATH`
30
+
31
+ ---
32
+
33
+ ## [0.1.0] — 2026-01-10
34
+
35
+ ### Added
36
+ - Initial public release
37
+ - 43 MCP tools wrapping the wikilite R package
38
+ - stdio transport (Claude Desktop / Claude Code)
39
+ - JSON-over-stdio R bridge (`r_bridge.py` + `mcp_interface.R`)
40
+ - Configuration for Claude Desktop (`config/mcp_config.json`)
41
+ - Windows installer script (`install.cmd`)
@@ -0,0 +1,224 @@
1
+ # Contributing to wikicitation-mcp
2
+
3
+ Thank you for your interest in contributing! This document explains how to
4
+ report bugs, request features, and submit code changes.
5
+
6
+ ---
7
+
8
+ ## Table of Contents
9
+
10
+ - [Code of Conduct](#code-of-conduct)
11
+ - [Reporting Bugs](#reporting-bugs)
12
+ - [Requesting Features](#requesting-features)
13
+ - [Development Setup](#development-setup)
14
+ - [Running the Test Suite](#running-the-test-suite)
15
+ - [Submitting a Pull Request](#submitting-a-pull-request)
16
+ - [Code Style](#code-style)
17
+ - [Adding or Modifying Tools](#adding-or-modifying-tools)
18
+ - [Support and Questions](#support-and-questions)
19
+
20
+ ---
21
+
22
+ ## Code of Conduct
23
+
24
+ This project follows the
25
+ [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/)
26
+ code of conduct. By participating you agree to abide by its terms. Please
27
+ report unacceptable behaviour to the repository maintainer via a private
28
+ GitHub message or the email address in `pyproject.toml`.
29
+
30
+ ---
31
+
32
+ ## Reporting Bugs
33
+
34
+ Before opening an issue, please:
35
+
36
+ 1. Search [existing issues](https://github.com/jsobel1/wikicitation-mcp/issues)
37
+ to avoid duplicates.
38
+ 2. Reproduce the bug on the latest commit of `main`.
39
+
40
+ When opening a bug report, include:
41
+
42
+ - Your operating system and Python version (`python --version`).
43
+ - Your R version (`R --version`) and `wikilite` version
44
+ (`packageVersion("wikilite")` inside R).
45
+ - The exact tool call or natural-language prompt that triggered the bug.
46
+ - The full error message and stack trace (Python side) or R traceback.
47
+ - Whether the bug is reproducible with a public Wikipedia article (preferred)
48
+ or only with a private/restricted one.
49
+
50
+ ---
51
+
52
+ ## Requesting Features
53
+
54
+ Open an issue with the label **enhancement**. Please describe:
55
+
56
+ - The Wikipedia citation analysis task you are trying to accomplish.
57
+ - Which existing `wikilite` R function, if any, would cover it (see the
58
+ [wikilite documentation](https://github.com/jsobel1/wikilite)).
59
+ - Any relevant API endpoints or data sources involved.
60
+
61
+ ---
62
+
63
+ ## Development Setup
64
+
65
+ ### Prerequisites
66
+
67
+ | Tool | Minimum version |
68
+ |------|----------------|
69
+ | Python | 3.10 |
70
+ | [uv](https://docs.astral.sh/uv/) | latest |
71
+ | R | 4.0 |
72
+ | wikilite R package | latest (`remotes::install_github("jsobel1/wikilite")`) |
73
+
74
+ ### Clone and install
75
+
76
+ ```bash
77
+ git clone https://github.com/jsobel1/wikicitation-mcp.git
78
+ cd wikicitation-mcp
79
+
80
+ # Create virtual environment and install dependencies
81
+ uv sync --dev
82
+ ```
83
+
84
+ ### Verify the R bridge
85
+
86
+ ```bash
87
+ uv run python -c "
88
+ import asyncio, json
89
+ from r_bridge import call_r_tool
90
+ result = asyncio.run(call_r_tool('count_citations', {'article': 'Zeitgeber'}))
91
+ print(json.dumps(result, indent=2))
92
+ "
93
+ ```
94
+
95
+ A successful response returns a JSON object with citation counts. If you see
96
+ a `RuntimeError`, check that `Rscript` is on your `PATH` and that `wikilite`
97
+ is installed in R.
98
+
99
+ ---
100
+
101
+ ## Running the Test Suite
102
+
103
+ ```bash
104
+ uv run pytest
105
+ ```
106
+
107
+ The suite has three levels:
108
+
109
+ | Level | What it tests | Requires R? |
110
+ |-------|--------------|-------------|
111
+ | Unit | JSON serialisation, error propagation, timeout handling | No |
112
+ | Bridge | Real `Rscript` subprocess against known wikitext | Yes |
113
+ | Integration | Live MediaWiki API calls (skipped if `wikilite` absent) | Yes + network |
114
+
115
+ To run only unit tests (no R needed):
116
+
117
+ ```bash
118
+ uv run pytest -k "not bridge and not integration"
119
+ ```
120
+
121
+ To run the full suite including live API calls:
122
+
123
+ ```bash
124
+ uv run pytest --run-integration
125
+ ```
126
+
127
+ All tests must pass before a pull request will be merged.
128
+
129
+ ---
130
+
131
+ ## Submitting a Pull Request
132
+
133
+ 1. **Fork** the repository and create a feature branch from `main`:
134
+
135
+ ```bash
136
+ git checkout -b feature/my-improvement
137
+ ```
138
+
139
+ 2. **Make your changes** following the code style guidelines below.
140
+
141
+ 3. **Add or update tests** — new MCP tools should have at least a unit test
142
+ (mocked subprocess) and a bridge test.
143
+
144
+ 4. **Update documentation** — if you add a tool, document it in `README.md`
145
+ under the appropriate category table.
146
+
147
+ 5. **Commit with a descriptive message**:
148
+
149
+ ```
150
+ Add get_citation_network tool for co-citation graph export
151
+ ```
152
+
153
+ 6. **Push and open a PR** against `main`. The PR description should explain
154
+ *what* changed and *why*, and link to any relevant issue.
155
+
156
+ Pull requests are reviewed by the maintainer. Please allow up to two weeks
157
+ for an initial response. Large or complex changes may require discussion
158
+ before implementation — consider opening an issue first.
159
+
160
+ ---
161
+
162
+ ## Code Style
163
+
164
+ **Python**
165
+
166
+ - Follow [PEP 8](https://peps.python.org/pep-0008/).
167
+ - Use type annotations for all function signatures.
168
+ - Keep MCP tool docstrings concise — they appear in the LLM tool catalogue.
169
+ - Format with [ruff](https://docs.astral.sh/ruff/):
170
+
171
+ ```bash
172
+ uv run ruff format .
173
+ uv run ruff check .
174
+ ```
175
+
176
+ **R**
177
+
178
+ - Follow the [tidyverse style guide](https://style.tidyverse.org/) for any
179
+ changes to `mcp_interface.R`.
180
+ - All R-level errors must be caught and returned as a JSON object with key
181
+ `"error"` so the Python bridge can re-raise them as descriptive
182
+ `RuntimeError` exceptions.
183
+
184
+ **Commits**
185
+
186
+ - Write commit messages in the imperative mood: *"Add …"*, *"Fix …"*, *"Remove …"*.
187
+ - Keep the subject line to 72 characters or fewer.
188
+ - Reference issue numbers where applicable: `Fix timeout on large articles (#12)`.
189
+
190
+ ---
191
+
192
+ ## Adding or Modifying Tools
193
+
194
+ `wikicitation-mcp` wraps functions from the `wikilite` R package. To add a
195
+ new tool:
196
+
197
+ 1. **Identify the `wikilite` function** you want to expose and its expected
198
+ arguments and return structure.
199
+
200
+ 2. **Add the R dispatch** in `mcp_interface.R` — add a case to the main
201
+ `switch` statement that calls the function and returns
202
+ `jsonlite::toJSON(result, auto_unbox = TRUE)`.
203
+
204
+ 3. **Register the MCP tool** in `server.py` using the `@mcp.tool()` decorator.
205
+ Provide a clear docstring and typed argument schema; the docstring text
206
+ is shown to the LLM as the tool description.
207
+
208
+ 4. **Write tests** — at minimum a unit test that mocks the subprocess and
209
+ verifies JSON round-tripping, and a bridge test that exercises the R
210
+ dispatch layer against known input.
211
+
212
+ 5. **Update `README.md`** — add a row to the relevant category table.
213
+
214
+ ---
215
+
216
+ ## Support and Questions
217
+
218
+ For general questions about usage, open a
219
+ [GitHub Discussion](https://github.com/jsobel1/wikicitation-mcp/discussions).
220
+ For bug reports and feature requests, use
221
+ [GitHub Issues](https://github.com/jsobel1/wikicitation-mcp/issues).
222
+
223
+ This project is maintained by a single developer. Response times may vary,
224
+ but all issues and PRs will receive a reply within two weeks.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jonathan Sobel
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.