wrice commited on
Commit
5baf0a5
·
unverified ·
2 Parent(s): 4dca8a82cca3c4

Merge pull request #2 from will-rice/perf/deferred-review-followups

Browse files

Deferred review follow-ups: bake embedding model, cap list_recent days

Files changed (4) hide show
  1. Dockerfile +3 -0
  2. src/papers_mcp/server.py +3 -2
  3. tests/test_server.py +9 -0
  4. uv.lock +2 -0
Dockerfile CHANGED
@@ -13,6 +13,9 @@ WORKDIR /app
13
 
14
  COPY --chown=user pyproject.toml uv.lock ./
15
  RUN uv sync --frozen --no-dev --no-install-project
 
 
 
16
  COPY --chown=user . .
17
  RUN uv sync --frozen --no-dev
18
 
 
13
 
14
  COPY --chown=user pyproject.toml uv.lock ./
15
  RUN uv sync --frozen --no-dev --no-install-project
16
+ # Bake the embedding model into the image so startup doesn't hit the HF Hub.
17
+ RUN uv run --no-sync python -c "from sentence_transformers import SentenceTransformer; \
18
+ SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2', device='cpu')"
19
  COPY --chown=user . .
20
  RUN uv sync --frozen --no-dev
21
 
src/papers_mcp/server.py CHANGED
@@ -26,6 +26,7 @@ CORPORA = {
26
  DATA_DIR = Path("data")
27
  REFRESH_INTERVAL_SECONDS = 6 * 60 * 60
28
  MAX_SEARCH_LIMIT = 50
 
29
 
30
  corpora: dict[str, Corpus] = {}
31
  indexes: dict[str, SearchIndex] = {}
@@ -128,8 +129,8 @@ def make_server(name: str) -> FastMCP:
128
  @mcp.tool()
129
  def list_recent(days: int = 30) -> str:
130
  """List papers submitted in the last N days, newest first."""
131
- if days < 1:
132
- raise ValueError("days must be at least 1")
133
  cutoff = (date.today() - timedelta(days=days)).isoformat()
134
  recent = sorted(
135
  (p for p in corpora[name].papers.values() if p.submitted >= cutoff),
 
26
  DATA_DIR = Path("data")
27
  REFRESH_INTERVAL_SECONDS = 6 * 60 * 60
28
  MAX_SEARCH_LIMIT = 50
29
+ MAX_RECENT_DAYS = 365
30
 
31
  corpora: dict[str, Corpus] = {}
32
  indexes: dict[str, SearchIndex] = {}
 
129
  @mcp.tool()
130
  def list_recent(days: int = 30) -> str:
131
  """List papers submitted in the last N days, newest first."""
132
+ if not 1 <= days <= MAX_RECENT_DAYS:
133
+ raise ValueError(f"days must be between 1 and {MAX_RECENT_DAYS}")
134
  cutoff = (date.today() - timedelta(days=days)).isoformat()
135
  recent = sorted(
136
  (p for p in corpora[name].papers.values() if p.submitted >= cutoff),
tests/test_server.py CHANGED
@@ -97,3 +97,12 @@ def test_list_recent_tool(client: TestClient) -> None:
97
  assert len(dates) > 5
98
  assert dates == sorted(dates, reverse=True) # newest first
99
  assert min(dates) >= (date.today() - timedelta(days=365)).isoformat()
 
 
 
 
 
 
 
 
 
 
97
  assert len(dates) > 5
98
  assert dates == sorted(dates, reverse=True) # newest first
99
  assert min(dates) >= (date.today() - timedelta(days=365)).isoformat()
100
+
101
+
102
+ def test_list_recent_days_over_cap_is_an_error(client: TestClient) -> None:
103
+ resp = client.post(
104
+ "/lipsync/mcp",
105
+ json=rpc("tools/call", {"name": "list_recent", "arguments": {"days": 366}}),
106
+ headers=MCP_HEADERS,
107
+ )
108
+ assert resp.json()["result"]["isError"] is True
uv.lock CHANGED
@@ -976,6 +976,7 @@ dependencies = [
976
  { name = "mcp" },
977
  { name = "rank-bm25" },
978
  { name = "sentence-transformers" },
 
979
  { name = "uvicorn" },
980
  ]
981
 
@@ -991,6 +992,7 @@ requires-dist = [
991
  { name = "mcp", specifier = ">=1.27,<2" },
992
  { name = "rank-bm25", specifier = ">=0.2.2" },
993
  { name = "sentence-transformers", specifier = ">=3.0" },
 
994
  { name = "uvicorn", specifier = ">=0.30" },
995
  ]
996
 
 
976
  { name = "mcp" },
977
  { name = "rank-bm25" },
978
  { name = "sentence-transformers" },
979
+ { name = "starlette" },
980
  { name = "uvicorn" },
981
  ]
982
 
 
992
  { name = "mcp", specifier = ">=1.27,<2" },
993
  { name = "rank-bm25", specifier = ">=0.2.2" },
994
  { name = "sentence-transformers", specifier = ">=3.0" },
995
+ { name = "starlette" },
996
  { name = "uvicorn", specifier = ">=0.30" },
997
  ]
998