{"id":50485140,"url":"https://github.com/vinodhalaharvi/suture","last_synced_at":"2026-06-01T21:30:28.055Z","repository":{"id":357431801,"uuid":"1236748196","full_name":"vinodhalaharvi/suture","owner":"vinodhalaharvi","description":"Healthcare AI superpowers and agents built on weft + MCP + FHIR. Submission for Prompt Opinion Agents Assemble.","archived":false,"fork":false,"pushed_at":"2026-05-12T19:01:54.000Z","size":105,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-12T20:13:08.398Z","etag":null,"topics":["agents","fhir","healthcare","mcp","prompt-opinion","weft"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vinodhalaharvi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-12T14:33:52.000Z","updated_at":"2026-05-12T19:02:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vinodhalaharvi/suture","commit_stats":null,"previous_names":["vinodhalaharvi/suture"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/vinodhalaharvi/suture","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinodhalaharvi%2Fsuture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinodhalaharvi%2Fsuture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinodhalaharvi%2Fsuture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinodhalaharvi%2Fsuture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vinodhalaharvi","download_url":"https://codeload.github.com/vinodhalaharvi/suture/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vinodhalaharvi%2Fsuture/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33795112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","fhir","healthcare","mcp","prompt-opinion","weft"],"created_at":"2026-06-01T21:30:27.290Z","updated_at":"2026-06-01T21:30:28.046Z","avatar_url":"https://github.com/vinodhalaharvi.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Suture — healthcare superpowers and agents on weft + MCP\n\nSuture is a set of healthcare AI tools built for the Prompt Opinion\n**Agents Assemble** hackathon. It demonstrates a working integration\nwith Prompt Opinion's published FHIR context spec, with the underlying\ntools composed using the [weft](https://github.com/vinodhalaharvi/weft)\nalgebra.\n\nThe thesis: every step of a clinical workflow — a FHIR read, a scoring\nrule, an LLM summarization, an agent loop — is a `weft.Arrow[A, B]`.\nThe same combinators (`Compose`, `Par`, `Pipe3`, `Traverse`, `Apply`)\noperate uniformly on every arrow regardless of how it was constructed.\n\n## What's in the box\n\nFive healthcare MCP tools, exposed over HTTP at `/mcp`:\n\n| Tool | Shape | What it shows |\n|---|---|---|\n| `get_patient_summary` | `Par + Map` | Two parallel FHIR reads merged into one typed output |\n| `calculate_cha2ds2_vasc` | `Pipe3` | FHIR reads → component extraction → scoring rules |\n| `get_cha2ds2_vasc_components` | `Compose` | Same building blocks composed differently |\n| `summarize_recent_encounters` | `Traverse + Apply` | Bounded-concurrency fan-out with `PartialResults` |\n| `prior_auth_assistant` | `Loop` over the others | Multi-step agent that orchestrates the superpowers |\n\n## Integration with Prompt Opinion\n\nSuture implements [Prompt Opinion's FHIR context spec for MCP servers](https://docs.promptopinion.ai/fhir-context/mcp-fhir-context):\n\n1. **Transport.** HTTP POST to `/mcp` carrying JSON-RPC 2.0 messages.\n2. **Capability declaration.** The `initialize` response includes\n   `capabilities.extensions[\"ai.promptopinion/fhir-context\"]` with the\n   SMART-on-FHIR scopes Suture's tools require:\n   - `patient/Patient.rs` (required)\n   - `patient/Condition.rs` (required)\n   - `patient/Encounter.rs` (optional)\n   - `patient/Observation.rs` (optional)\n3. **Context propagation.** Every `tools/call` request carries the FHIR\n   context as HTTP headers:\n   - `X-FHIR-Server-URL` — the FHIR base URL\n   - `X-FHIR-Access-Token` — SMART bearer token (optional)\n   - `X-Patient-ID` — current patient\n4. **Token handling.** The token is passed verbatim as a `Bearer`\n   header on every FHIR request. If no token is supplied, no\n   `Authorization` header is sent — per the spec, some FHIR servers\n   don't require auth.\n\n## Quick start\n\n```bash\ngit clone https://github.com/vinodhalaharvi/suture.git\ncd suture\ngo test ./...           # all tests pass, race-clean\ngo build ./...\n\n# Run the MCP server (HTTP on :8080):\n./suture-server\n\n# Or pick a different port:\nPORT=9090 ./suture-server\n\n# List the registered tools:\n./suture-server -list\n\n# Call a tool directly via HTTP (mimics what Prompt Opinion does):\ncurl -X POST http://localhost:8080/mcp \\\n    -H \"Content-Type: application/json\" \\\n    -H \"X-FHIR-Server-URL: https://hapi.fhir.org/baseR4\" \\\n    -H \"X-Patient-ID: 12345\" \\\n    -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"get_patient_summary\",\"arguments\":{}}}'\n```\n\n### Local CLI demo (no Prompt Opinion required)\n\n```bash\n./demo \\\n    -tool get_patient_summary \\\n    -fhir https://hapi.fhir.org/baseR4 \\\n    -patient 1234567\n\n# To use the prior_auth_assistant agent:\nexport ANTHROPIC_API_KEY=sk-ant-...\n./demo \\\n    -tool prior_auth_assistant \\\n    -patient 1234567 \\\n    -request \"apixaban for atrial fibrillation\"\n```\n\n### Registering with Prompt Opinion\n\n1. Deploy `suture-server` somewhere reachable (Fly.io, Cloud Run, Railway, etc.).\n2. In the Prompt Opinion web app, go to `Configuration → MCP Servers`.\n3. Paste your deployed URL (e.g., `https://suture.fly.dev/mcp`).\n4. Click `Continue`. The platform sends `initialize` and reads the\n   FHIR context extension. You'll be shown the SMART scopes the server\n   requests; authorize them.\n5. The platform now invokes Suture's tools with the FHIR headers\n   attached. The full integration test in\n   `cmd/suture-server/main_test.go` simulates this exact flow against\n   a faithful HTTP test client.\n\n## Configuration via environment variables\n\n```bash\nPORT=8080                          # HTTP port (default 8080)\nANTHROPIC_API_KEY=sk-ant-...       # required only for prior_auth_assistant\n```\n\nThat's the complete config surface for production.\n\n## Architecture\n\n```\n┌──────────────────────────────────────────────────────────────┐\n│  Prompt Opinion platform                                     │\n│  (HTTP POST to /mcp with FHIR context headers)               │\n└─────────────────────────┬────────────────────────────────────┘\n                          │\n┌─────────────────────────▼────────────────────────────────────┐\n│  cmd/suture-server                                           │\n│  HTTP listener → JSON-RPC dispatch                           │\n└─────────────────────────┬────────────────────────────────────┘\n                          │\n┌─────────────────────────▼────────────────────────────────────┐\n│  internal/mcp                                                │\n│  Stashes HTTP headers into context.Context                   │\n│  Declares ai.promptopinion/fhir-context extension            │\n└─────────────────────────┬────────────────────────────────────┘\n                          │\n┌─────────────────────────▼────────────────────────────────────┐\n│  internal/fhircontext                                        │\n│  Reads X-FHIR-Server-URL / X-FHIR-Access-Token / X-Patient-ID│\n│  Injects typed fhircontext.Context for downstream arrows     │\n└─────────────────────────┬────────────────────────────────────┘\n                          │\n┌─────────────────────────▼────────────────────────────────────┐\n│  internal/fhir + pkg/tools + pkg/agent                       │\n│  weft.Arrow values composed via Pipe3, Par, Traverse, …      │\n└──────────────────────────────────────────────────────────────┘\n```\n\nThe integration-specific code (HTTP transport + header extraction) is\nisolated in `internal/mcp/http.go` and `internal/fhircontext`. The FHIR\nclient, tool arrows, agent loop, and tests below that line are\nplatform-agnostic.\n\n### Request flow (sequence diagram)\n\nFor a clearer picture of what happens on the wire during a clinician's\ntool invocation, see [`docs/sequence-flow.svg`](docs/sequence-flow.svg).\nIt walks through three phases:\n\n1. **One-time MCP server registration.** Prompt Opinion sends `initialize`,\n   reads the FHIR context capability extension, and shows the user a\n   SMART scope authorization screen.\n2. **A simple tool call.** `get_patient_summary` invocation showing the\n   FHIR context headers flowing in, `weft.Par` firing two parallel FHIR\n   reads, and a typed result going back through the MCP envelope.\n3. **The agent loop.** `prior_auth_assistant` running an LLM tool-use\n   loop with Claude, calling other Suture tools as bindings, returning\n   a drafted letter — all behind a single synchronous MCP request.\n\nThe two architecturally interesting moments are visible in the diagram:\nthe `weft.Par` parallel-FHIR fan-out (no goroutine plumbing in user\ncode), and the agent loop running entirely inside a single MCP call\nwith no separate workflow engine.\n\n## Test suite\n\n```bash\nmake test          # all packages\nmake test-race     # under the race detector\nmake cover         # HTML coverage report\n```\n\nThe headline test is in `cmd/suture-server/main_test.go`: it spins up\na real HTTP MCP server, simulates Prompt Opinion's exact calling\npattern (POST `/mcp` with `X-FHIR-Server-URL`, `X-FHIR-Access-Token`,\n`X-Patient-ID` headers), and verifies the full stack — header\nextraction → FHIR context propagation → weft arrow → authenticated\nFHIR call → typed output. If that test passes, the integration is real.\n\n## Layout\n\n```\n.\n├── cmd/\n│   ├── suture-server/        the MCP server binary\n│   └── demo/                 local CLI for testing tools against a FHIR sandbox\n├── internal/\n│   ├── mcp/                  HTTP + stdio MCP transport, capability extensions\n│   ├── fhircontext/          Prompt Opinion FHIR context propagation\n│   └── fhir/                 typed FHIR R4 client as weft Arrows\n├── pkg/\n│   ├── agent/                LLM tool-use loop combinator\n│   └── tools/                the five healthcare tools\n├── docs/\n│   ├── architecture.svg      static integration diagram\n│   └── sequence-flow.svg     request-flow sequence diagram (with sources)\n└── examples/                 sample MCP request bodies\n```\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvinodhalaharvi%2Fsuture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvinodhalaharvi%2Fsuture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvinodhalaharvi%2Fsuture/lists"}