Connect your AI assistant to Serin
Ask about your portfolio in ChatGPT or another assistant you already use. Serin shares read-only portfolio results with the assistant you connect. The assistant and its provider receive the data it requests; your portfolio stays stored in Serin. Connecting does not let an assistant place trades or edit your portfolio.
You will find the same Connect your AI entry in Serin's navigation on both Cloud and self-hosted instances. You do not need the server's Connectors settings.
ChatGPT
Use ChatGPT in your browser and keep Serin open in another tab. You need a ChatGPT account/workspace that allows Developer mode and a Serin server with ChatGPT account linking enabled. Serin's setup page tells you if it is available.
- Enable custom connections. In ChatGPT, open Settings → Security and login → Developer mode. Turn it on, then open Plugins and select + to add a connection. If the setting is missing, check with your workspace administrator or use an account that supports custom connections.
- Add Serin. Name the connection Serin. Copy the Server URL from Serin's Connect your AI → ChatGPT page into ChatGPT. Select OAuth for authentication. Leave client ID and client secret blank if optional; Serin registers ChatGPT automatically. If a description is requested, enter Read-only access to my Serin portfolio.
- Approve your account. Follow ChatGPT's connection prompts. When Serin opens, sign in if needed, check the account shown, and select Allow read-only access. You will return to ChatGPT automatically. You do not need to create or paste an agent token, install Python, or download a file.
- Ask your first question. Start a new ChatGPT conversation, add Serin from its tools menu, and ask:
Use Serin to summarize my portfolio and tell me when its prices were last updated.
- Check it worked. Return to Serin's Connect your AI → Your connections. After a successful portfolio tool request it shows Working and the last use time. Approved · ask your first question means access was approved but Serin has not yet answered a successful MCP tool request.
OpenAI may change its menu labels. The official ChatGPT connection guide is the reference for the current ChatGPT interface.
Disconnect or change accounts
In Connect your AI → Your connections, select Disconnect beside ChatGPT. This immediately invalidates that connection's access and refresh credentials. It does not disconnect a brokerage or delete results already in a ChatGPT chat. To switch accounts, disconnect and repeat setup, signing in to the intended Serin account on the approval page.
If ChatGPT cannot connect
- Developer mode is missing: availability depends on your ChatGPT account and workspace policy. Ask your workspace administrator.
- Serin says ChatGPT is unavailable: account linking is not configured on that server. Cloud users should contact support; self-hosters should use the server setup below. A manual agent token is not a substitute for the ChatGPT OAuth flow.
- Authentication error: use the full Server URL copied from Serin, including
/api/agent/mcp, and choose OAuth. Do not select “No authentication” or paste a Serin password into client-secret fields. - Request expired or a different browser: start again from ChatGPT and complete sign-in and approval in the same browser within ten minutes.
- Connected, but no portfolio answer: start a new chat, add Serin from the tools menu, and explicitly ask it to use Serin. Refresh the connection's tools in ChatGPT if you created it before a server update.
Self-hosted ChatGPT setup
ChatGPT must reach your Serin server over public HTTPS. A localhost URL is not reachable from ChatGPT web. The server operator must:
- Enable Serin sign-in (
SERIN_AUTH_PASSWORD, or the hosted account provider). - Set
SERIN_APP_URLto the canonical public HTTPS origin, for examplehttps://portfolio.example.com, with no/appor/apipath. - Use the same
SERIN_SECRET_KEYon every server worker and preserve it across deployments. It signs client registrations and short-lived approval requests. - Forward
/.well-known/*,/oauth/*,/api/*and/appto the same Serin deployment. Do not put a second interactive login in front of the OAuth discovery and token endpoints.
Restart Serin after configuration, then follow the ChatGPT steps above. The Server URL in the app is generated from this canonical origin. Account linking stays unavailable if a public HTTPS origin or Serin sign-in is missing.
For operators: this integration supports ChatGPT dynamic client registration, OAuth authorization code with S256 PKCE, one-hour access tokens, rotating 30-day refresh tokens, and account-scoped revocation. Client registration is restricted to ChatGPT's HTTPS callback addresses. It is not a general OAuth provider for arbitrary clients; use the token flow below for other MCP clients.
Other MCP clients
Choose Connect your AI → Other MCP clients. Give the connection a name, then select Create read-only token. Save it when shown: it cannot be revealed again. If you lose it, disconnect that token and create another.
A token gives its holder read access to your account's portfolio. Keep it private and put it only in your client's credential settings, never in a chat message or URL. The Copy buttons copy the server URL and token separately.
For a client that supports remote MCP with custom headers:
Server URL: copy from Serin's Connect your AI page
Authorization: Bearer YOUR_TOKEN
Use the local bridge below only if your client can launch local commands. ChatGPT web uses the OAuth steps above; these JSON configuration files are not its setup flow.
What it can and cannot do
It can read: totals and weights, real time-weighted and money-weighted returns, FIFO-matched realised gains, individual holdings and their tax lots, transactions, cached price history, and the data-quality gaps that would make any of those unreliable.
It cannot write. There is no tool to add, edit or delete a position, and the tool registry refuses to accept one — a hallucinated edit would corrupt cost basis, which is the number the whole product exists to get right.
It does not give financial advice, and it is not a trading interface.
Answers come back already computed. Ask "what's my YTD return" and the model receives the number Serin calculated, not forty rows to add up itself.
Local bridge and advanced setup
Which recipe you want depends on what you have on the machine running the AI client, not on which client it is.
| Your situation | Use |
|---|---|
| Serin Cloud | Remote MCP, or the one-file bridge |
| Self-hosted with Docker | Docker, or remote MCP |
| Self-hosted from a checkout | From a checkout |
These alternatives expose the same portfolio tools. Choose the one your client supports.
A. Remote MCP (nothing to install)
The simplest path if your client supports remote MCP servers:
URL: https://your-serin/api/agent/mcp
Header: Authorization: Bearer serin_at_...
Copy the exact URL from Connect your AI on your instance. This avoids redirects between different hostnames.
One endpoint, one JSON-RPC message per request, stateless. Client support for remote servers with bearer auth is still uneven — if yours cannot, use the one-file bridge below, if your client supports launching local commands.
B. The one-file bridge
For Serin Cloud, or any machine with no checkout and no container. The bridge is a thin HTTP client with no Serin dependencies, so it runs on its own:
curl -O https://raw.githubusercontent.com/aviary-ai-labs/serin/main/backend/mcp_server.py
pip install httpx
Then point your client at it, using an absolute path:
{
"mcpServers": {
"serin": {
"command": "python",
"args": ["/absolute/path/to/mcp_server.py"],
"env": {
"SERIN_URL": "https://serin.money",
"SERIN_AGENT_TOKEN": "serin_at_..."
}
}
}
}
Needs Python 3.10 or newer and httpx, nothing else. Self-hosters: set
SERIN_URL to wherever you reach Serin in a browser.
C. Inside the container
If you run Serin with docker compose up, you have no checkout — but the image
already contains the bridge, so run it there:
{
"mcpServers": {
"serin": {
"command": "docker",
"args": [
"exec", "-i",
"-e", "SERIN_URL=http://127.0.0.1:8890",
"-e", "SERIN_AGENT_TOKEN=serin_at_...",
"serin",
"python", "-m", "backend.mcp_server"
]
}
}
}
serin is the container name from docker-compose.yml, and it must be running
when the client starts. 127.0.0.1:8890 is correct here because the command
runs inside the container.
D. From a checkout
{
"mcpServers": {
"serin": {
"command": "python",
"args": ["-m", "backend.mcp_server"],
"cwd": "/path/to/your/serin/checkout",
"env": {
"SERIN_URL": "http://127.0.0.1:8890",
"SERIN_AGENT_TOKEN": "serin_at_..."
}
}
}
}
Where your client keeps its config
The JSON above goes in your client's MCP config file.
Claude Desktop
- macOS —
~/Library/Application Support/Claude/claude_desktop_config.json - Windows —
%APPDATA%\Claude\claude_desktop_config.json
Create it if it isn't there, then restart the app.
Claude Code
claude mcp add serin \
-e SERIN_URL=https://serin.money \
-e SERIN_AGENT_TOKEN=serin_at_... \
-- python /absolute/path/to/mcp_server.py
Flags move between releases — claude mcp add --help is authoritative.
Cursor, Cline, Zed and others use the same mcpServers shape but keep it in
their own file. Copy the block above and check your client's MCP documentation
for where that lives.
What you can ask
- How am I doing this year?
- What's my biggest position, and how concentrated am I?
- What did I realise in 2025, and how much was short-term?
- Are any of my prices stale?
- What's missing from my data that would make these numbers wrong?
Serin reports how fresh its prices are with every answer that uses them, so your assistant can tell a current quote from a cached one.
Not using MCP?
The same tools are plain HTTP, published in /openapi.json — enough for
LangChain, LlamaIndex, OpenAI function calling, or your own loop:
| Endpoint | What it does |
|---|---|
GET /api/agent/tools |
Every tool with its JSON schema |
POST /api/agent/tools/{name} |
Run one; arguments are the JSON body |
GET /api/agent/context.md |
The whole portfolio as Markdown |
POST /api/agent/mcp |
MCP over HTTP |
context.md is the zero-integration option: it works with any assistant at
all, including ones with no tool support, and you can paste it into a chat
window yourself.
Troubleshooting
The client shows no tools. It never finished connecting. Check the client's
MCP log: a bridge that cannot import backend.mcp_server exits immediately.
Use the Docker recipe, or set cwd to a Serin checkout.
401 Unauthorized. SERIN_AGENT_TOKEN is missing, mistyped, or revoked.
Tokens are shown once — make a new one rather than guessing.
403 Forbidden. That credential isn't an agent token. A session token or app
passphrase will not work here; agent tokens start with serin_at_.
Connection refused. SERIN_URL is wrong. On Cloud it is
https://serin.money — with the scheme, and no trailing path. From inside the
container it is http://127.0.0.1:8890. From your own machine against a
self-hosted box, it is wherever you reach Serin in a browser.
ModuleNotFoundError: No module named 'backend'. You used a
checkout-shaped recipe without a checkout. Use the one-file bridge (B) or the
Docker recipe (C).
Answers cite old prices. That is Serin being honest — the price cache survives a failed refresh, and every tool reports its own staleness. Run a price refresh.
On Serin Cloud (and any shared deployment)
A token names the account that issued it (serin_at_<account>.<secret>) and
every request runs bound to that account, so it reads your portfolio and no one
else's. The account half is not a secret; swapping it for someone else's looks
up their stored hashes, which will not match, so a token cannot be pointed at
another account.