One MCP Server, Two AI Clients: Wiring Actian VectorAI DB Into Claude and Cursor A developer built a single MCP server in about 230 lines of Python to connect Actian VectorAI DB to both Claude and Cursor, demonstrating the protocol's promise of one server for any AI client. The server exposes six tools, handles embeddings locally, and was verified at the protocol layer, with the build published on GitHub. MCP promises one server, any AI client. I put that to the test by wiring Actian VectorAI DB up to Claude and Cursor with a single ~230-line Python file, and verified every claim about it at the protocol layer rather than taking anything on faith. Build's public on GitHub. Every vector database has its own SDK. Every AI assistant has its own plugin format. Want Claude and Cursor to search your vector DB? That's normally two separate integrations, and a third tool next month makes three. MCP removes that last part. It's an open protocol originally from Anthropic that lets any MCP-aware client Claude Desktop, Claude Code, Cursor, whatever comes next talk to the same server over a standard interface. Write the server once, every client gets it for free. I built a small MCP server for Actian VectorAI DB , a portable, local-first vector database, to see if that promise holds up. Six tools, ~230 lines of Python, one file: | Tool | What it does | |---|---| create collection | Idempotently creates a 384-dim collection with a chosen distance metric | ingest documents | Embeds text and upserts it, payload included | search | Embeds a query, returns top-k ranked hits | list collections | Lists what's in the instance | get collection info | Point count, status, vector config | delete collection | Deletes it, no confirmation step | The one design decision I'd defend to the death: the LLM never sees a vector. Every tool's input and output is plain strings, lists, and JSON dicts. The embedding happens inside the server process sentence-transformers running all-MiniLM-L6-v2 locally on CPU , so Claude or Cursor only ever reasons about text and decides when to call search . LLMs are bad at generating 384 floating point numbers that mean something; they're good at calling a function with a query: str argument. php Claude / Cursor <--stdio JSON-RPC-- server.py FastMCP <--gRPC-- Actian VectorAI DB │ sentence-transformers local, 384-dim embeddings It's a reference implementation, sized for a stage: a single global DB, running locally, built around a demo-sized dataset six sentences, for this build . Before locking in get collection info , I checked what the response looked like against the installed actian-vectorai-client==1.0.2 , rather than coding purely off memory. Point count and status come back directly from that call, but not vector config size/distance , so get collection info pulls those two things from two places: gRPC for point count and status, and the REST API port 6573 for vector config. First, examples/demo.py running straight against the live DB, plain Python calling the SDK directly: created a collection, ingested 6 FAQ sentences, searched, and got the right result back. Then fastmcp.Client , to drive server.py over stdio JSON-RPC, the same path Claude and Cursor use. This is what confirmed get collection info was pulling the right data from both the gRPC and REST calls, something that only became visible once data flowed through the full protocol path. I also pointed the server at a dead port on purpose, just to confirm every tool failed with a plain-English message instead of a stack trace. At the OS process level, I confirmed Cursor itself had spawned the MCP server subprocess after reloading, proof the config was picked up and working. And finally, calling search through that MCP connection and getting back {"text": "Submissions close Sunday at 9am."} for "submission deadline for the hackathon," score 0.4227 . Create a collection called notes . Collection 'notes' is ready distance=cosine, dim=384 . Add these three facts to notes : submissions close Sunday at 9am, first prize is $2,000, teams can have 2-5 members. Inserted 3 document s into collection 'notes'. What's the submission deadline? {"score": 0.4777, "payload": {"text": "Submissions close Sunday at 9am."}} , which the assistant turns into "the deadline is Sunday at 9am." Then the point of the whole exercise: ask the same question in Cursor, switch windows, ask it again in Claude Desktop. Only the client-specific config block differs between the two. I picked Actian VectorAI DB for being local-first, no cloud dependency, which mattered for a live demo on conference wifi. The Community Edition is free and was enough for this entire build. If you want to spin it up yourself, the Docker setup instructions https://docs.vectoraidb.actian.com/home/installation/instructions cover both a plain docker run and a docker-compose.yml . The bigger point, though: one small MCP server, any MCP client, natural language in, semantic search out, no vectors ever exposed to the model. If you've got an SDK and a thing worth calling from an LLM, this is basically the whole recipe. You can find the repo here https://github.com/gerimate/vectorai-mcp-server .