@pipeworx/mcp-openstates 0.1.4 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeworx/mcp-openstates",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "OpenStates MCP — bills, legislators, votes in all 50 US states",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -26,7 +26,7 @@
26
26
  "@cloudflare/workers-types": "^4.20260405.1"
27
27
  },
28
28
  "pipeworx": {
29
- "sourceHash": "v1-d9939703c0e177f41da0fbd131835af380ebc15e9c75b8fd58b9dbebd35552be",
30
- "sourceCommit": "69152ffc15233d5998bfe6fe195c040cdb328366"
29
+ "sourceHash": "v1-732159c87c7a46974cc5b92992d343278cc7c9e5f77023cc3f442dfd8969be69",
30
+ "sourceCommit": "ca77f046c3ddc52178f0c89d5682d4625c655201"
31
31
  }
32
32
  }
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.pipeworx-io/openstates",
4
4
  "title": "Openstates",
5
5
  "description": "OpenStates MCP — bills, legislators, votes in all 50 US states",
6
- "version": "0.1.4",
6
+ "version": "0.1.5",
7
7
  "websiteUrl": "https://pipeworx.io/packs/openstates",
8
8
  "repository": {
9
9
  "url": "https://github.com/pipeworx-io/mcp-openstates",
package/src/index.ts CHANGED
@@ -909,13 +909,19 @@ async function searchBills(apiKey: string, args: Record<string, unknown>) {
909
909
  bills: (data.results ?? []).map((b) => normalizeBill(b, false)),
910
910
  });
911
911
 
912
+ // Session ids are per-state (fleet #2465), so a zero under a session filter
913
+ // is as likely a wrong-shaped id as a genuine no-match. A year-shaped value
914
+ // is the common wrong shape: fetch the state's session list ALONGSIDE the
915
+ // search rather than after it, so the retry costs one extra round trip, not
916
+ // two — ask_pipeworx gives a leg ~13s and this upstream is slow.
917
+ const resolutionP: Promise<Settled> | null =
918
+ session && yearRangeOf(session) ? resolveSession(apiKey, jurisdiction, session).then(ok, fail) : null;
912
919
  const data = await osFetch<BillsPage>(apiKey, '/bills', params);
913
920
  if (!session || (data.results?.length ?? 0) > 0) return shape(data);
914
921
 
915
- // Zero rows WITH a session filter: session ids are per-state (fleet #2465),
916
- // so a zero here is as likely a wrong-shaped id as a genuine no-match. Check
917
- // it against the state's own session list before reporting an empty result.
918
- const resolution = await resolveSession(apiKey, jurisdiction, session);
922
+ const settled = resolutionP ? await resolutionP : await resolveSession(apiKey, jurisdiction, session).then(ok, fail);
923
+ if ('error' in settled) throw settled.error;
924
+ const resolution = settled.value;
919
925
  if (resolution.exact) return shape(data, { session_checked: resolution.exact });
920
926
 
921
927
  let last = data;
@@ -934,6 +940,11 @@ async function searchBills(apiKey: string, args: Record<string, unknown>) {
934
940
  });
935
941
  }
936
942
 
943
+ type Resolution = { exact?: string; candidates: OsSession[] };
944
+ type Settled = { value: Resolution } | { error: unknown };
945
+ const ok = (value: Resolution): Settled => ({ value });
946
+ const fail = (error: unknown): Settled => ({ error });
947
+
937
948
  function sessionNote(requested: string, used: string, name: string | undefined, candidates: OsSession[]) {
938
949
  return {
939
950
  requested,
@@ -1009,11 +1020,12 @@ export function resolveSessionCandidates(requested: string, sessions: OsSession[
1009
1020
  .slice(0, 4);
1010
1021
  }
1011
1022
 
1012
- // OpenStates does not always populate `classification` (Texas leaves it off and
1013
- // names its specials "…Called Session"), so read the name too — otherwise the
1014
- // newest special session outranks the regular one for the same year.
1023
+ // Otherwise the newest special session outranks the regular one for the same
1024
+ // year ("2025" in Texas picked "892" over "89R").
1025
+ // Live Texas marks its called sessions `primary` too, so the name is the
1026
+ // signal that actually separates them; `classification` only adds to it.
1015
1027
  function isSpecialSession(s: OsSession): boolean {
1016
- if (s.classification) return s.classification !== 'primary';
1028
+ if (s.classification === 'special') return true;
1017
1029
  return /\b(special|called|extraordinary|extra)\b/i.test(s.name ?? '');
1018
1030
  }
1019
1031
 
@@ -1085,7 +1097,9 @@ async function resolveSession(
1085
1097
 
1086
1098
  async function getBill(apiKey: string, args: Record<string, unknown>) {
1087
1099
  const id = (args.openstates_id as string | undefined)?.trim();
1088
- const params = new URLSearchParams({ include: 'sponsorships,actions,votes,versions,sources,abstracts' });
1100
+ // v3 takes `include` REPEATED; a comma-joined value is a 422 on every call.
1101
+ const params = new URLSearchParams();
1102
+ for (const inc of ['sponsorships', 'actions', 'votes', 'versions', 'sources', 'abstracts']) params.append('include', inc);
1089
1103
 
1090
1104
  if (id) {
1091
1105
  const data = await osFetch<OsBill>(apiKey, `/bills/${encodeURIComponent(id)}`, params);
package/src/server.ts CHANGED
@@ -9,7 +9,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
9
9
  import pack from './index.js';
10
10
 
11
11
  const server = new Server(
12
- { name: '@pipeworx/mcp-openstates', version: '0.1.4' },
12
+ { name: '@pipeworx/mcp-openstates', version: '0.1.5' },
13
13
  { capabilities: { tools: {} } },
14
14
  );
15
15