Back to Browse

Billing Tracker Agent Plugins MCP Server

Developer ToolsLow Risk10.0MCP RegistryRemote
Free

Server data from the Official MCP Registry

Personal bill tracker: due dates, payments and spending reports. Sign in with Google or LINE.

About

Personal bill tracker: due dates, payments and spending reports. Sign in with Google or LINE.

Remote endpoints: streamable-http: https://bills.jirawat.dev/mcp

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (1 strong, 1 medium validity signals). No known CVEs in dependencies. Imported from the Official MCP Registry.

Endpoint verified · Requires authentication · 1 issue found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Found in Source Code

Found by scanning the linked source code. This listing connects to a hosted endpoint, so none of this runs on your machine: it describes what the server software does where it is hosted.

file_system

Applies to the server that hosts this plugin, not to your machine.

Shell Command Execution

Runs commands on the server that hosts it, not on your machine.

HTTP Network Access

Connects to external APIs or services over the internet.

How to Connect

Remote Plugin

No local installation needed. Your AI client connects to the remote endpoint directly.

Add this to your MCP configuration to connect:

{
  "mcpServers": {
    "io-github-jirawatp-billing-tracker": {
      "url": "https://bills.jirawat.dev/mcp"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

Bill Tracker agent plugins

CI

Connect your AI agent to Bill Tracker, a personal bill tracker with LINE reminders. Once connected, your agent can tell you what is due or overdue, record payments, add and edit bills, and summarize your spending, all through your own Bill Tracker account.

This repository holds the plugins, connector settings and agent skill. They all point at one remote MCP server:

https://bills.jirawat.dev/mcp

[!NOTE] The Bill Tracker MCP server was deployed on 20 October 2026. Public metadata and the OAuth sign-in challenge have passed the deployment smoke check. Google sign-in and 21 live OAuth/MCP checks passed with the official JavaScript SDK, including bill writes, refresh and revocation. The user also verified LINE QR sign-in in the browser and reached the bill ledger. The individual client setups below still need their own live compatibility checks.

Contents

What is in this repository

  • One plugin that bundles the MCP server and the billing-tracker agent skill. It installs natively in Claude Code, Codex and the ChatGPT desktop app, Cursor, VS Code, GitHub Copilot CLI, Gemini CLI and Antigravity CLI.
  • Plugin marketplaces, so Claude Code, GitHub Copilot CLI, VS Code and Codex can add this repository as a marketplace and keep the plugin updated.
  • A server.json for the official MCP Registry.
  • Copy-paste settings for clients that connect to MCP servers directly: Claude apps, ChatGPT, Windsurf, Cline, Zed and stdio-only clients.
  • A portable Agent Skill that teaches agents to use the bill tools well: common tasks, confirming before destructive changes, and handling dates and Thai Baht amounts.

Every configuration names the server bills.

Before you start

  • A Bill Tracker account. Sign in once at Bill Tracker with Google or LINE to create one.
  • An MCP client that supports remote servers. The server uses the Streamable HTTP transport with OAuth sign-in. Every client below supports that; clients that can only start local (stdio) servers can use the mcp-remote bridge.
  • A current client. The server speaks MCP protocol revisions 2025-11-25 (preferred) and 2025-06-18 through the standard initialize handshake that current clients use. If a client offers another revision in initialize, the server answers with 2025-11-25; the client decides whether it can continue. Other requests with an unsupported MCP-Protocol-Version header get error -32022. The server uses Streamable HTTP only, without the legacy HTTP+SSE transport, so clients limited to 2025-03-26 or older may not connect.

Sign-in, permissions and privacy

  • You sign in with your own account. The first time your agent connects, a browser window opens on the Bill Tracker site. Sign in with the same Google or LINE account you use in the app, then review the consent screen, which shows the agent's name and the permissions it asks for. You never need a client ID, secret or API key: clients discover the sign-in flow on their own through standard MCP authorization (OAuth 2.1 with PKCE, client registration through Client ID Metadata Documents or Dynamic Client Registration).
  • You only see your own bills. Every request runs as the account that signed in. An agent connected to your account cannot reach anyone else's bills.
  • Permissions are granted step by step. By default the first sign-in asks for bills:read, bills:write and offline_access, which lets your client renew the session without another browser sign-in. Some clients, such as Codex, ask for every advertised permission up front. When the agent first uses a tool that needs more, the server asks for that permission and your client either reopens the consent screen or asks you to sign in to the server again.
  • Deleting your account always takes a separate approval. No client can request the account:delete permission during sign-in. If you ask an agent to delete your account, its first attempt is refused; you then open Settings > Connected AI agents and approve the deletion on its own consent screen after a recent sign-in. The permission expires at that original sign-in time plus five minutes; approval and code exchange do not restart the clock. No refresh token is issued.
  • You can disconnect any agent. Open Settings > Connected AI agents in Bill Tracker to see every connected agent and personal access token, and revoke any of them. Signing out of Bill Tracker on all devices does not disconnect agents; revoke them on that page.
  • Destructive actions need confirmation. The server refuses to delete bills, unlink LINE or delete your account unless the request carries an explicit confirmation, and the included skill tells agents to ask you first.
  • This repository holds no data and no secrets. It contains only configuration and instructions. Your MCP client stores your sign-in tokens, and your bills stay in Bill Tracker.

Read the service's Privacy Policy and Terms of Service before connecting a client.

PermissionLets the agent
bills:readList, search and read bills and summaries, including the read commands of chat.run
bills:writeAdd and edit bills, record payments, confirm amounts, schedule payments
bills:deleteDelete bills
reports:readRead spending reports
account:readExport all of your data
account:manageSign you out on every device, turn LINE reminders on or off, unlink LINE
account:deleteDelete your Bill Tracker account. Approved separately after a recent sign-in; expires at that sign-in plus five minutes, with no refresh
line:readSee whether LINE is linked and reminders are on
chat:readParse LINE chatbot commands without running them or reading bills
chat:writeRun any LINE chatbot command, including commands that only read data; deleting also needs bills:delete
offline_accessStay signed in: renew the session without another browser sign-in

Choose your client

ClientRecommended setupIncludes the skill
Claude CodePlugin from this marketplaceYes
Claude apps (claude.ai, Claude Desktop, mobile)Custom connectorUpload it separately
ChatGPT (Business, Enterprise and Edu, on the web)Custom MCP server, created as a pluginNo
Codex (CLI, IDE extension, ChatGPT desktop app)Plugin from this marketplaceYes
CursorOne-click install link, or local pluginWith the plugin
VS Code and GitHub CopilotOne-click install link, or plugin from sourceWith the plugin
GitHub Copilot CLIPlugin from this marketplaceYes
Gemini CLIExtensionYes
Antigravity CLIPluginYes
Windsurfmcp_config.json entryNo
ClineRemote serverNo
Zedcontext_servers entryNo
Stdio-only clientsmcp-remote bridgeNo

Any agent that supports Agent Skills can add the skill on its own; see Skill only. Use one setup per client: installing the plugin and also adding the server by hand gives you every tool twice.

Install

Claude Code

Install the plugin, which adds the MCP server and the skill. Inside Claude Code:

/plugin marketplace add jirawatp/billing-tracker-agent-plugins
/plugin install billing-tracker@billing-tracker

Or from a terminal:

claude plugin marketplace add jirawatp/billing-tracker-agent-plugins
claude plugin install billing-tracker@billing-tracker

Then run /reload-plugins (or restart Claude Code), open /mcp, select plugin:billing-tracker:bills and choose Authenticate.

To add only the server, for every project:

claude mcp add --transport http --scope user bills https://bills.jirawat.dev/mcp
claude mcp login bills

On a machine without a browser, claude mcp login bills --no-browser prints the sign-in URL and asks you to paste the redirect URL back.

If a tool later fails with "needs additional permissions", open /mcp and authenticate the server again to approve the extra permission.

Claude apps (claude.ai, Claude Desktop, mobile)

Add Bill Tracker as a custom connector. Custom connectors are available on the Free (one custom connector), Pro, Max, Team and Enterprise plans, and once added they work in claude.ai, Claude Desktop, Cowork and the mobile apps.

  1. Go to Customize > Connectors, select + Add, then Add custom connector.
  2. Enter the name Bill Tracker and the URL https://bills.jirawat.dev/mcp, then select Continue.
  3. Under Authentication, choose Sign in now. Under OAuth client, keep Use Claude's published identity (Recommended). Leave Request headers empty.
  4. Select Add, then sign in with Google or LINE in the window that opens.
  5. In a chat, turn the connector on from the + menu under Connectors.

On Team and Enterprise plans an Owner adds the connector in the organization settings, and each member then connects their own Bill Tracker account. Claude reaches the server from Anthropic's cloud, not from your computer.

To add the skill as well, turn on Code execution and file creation in Settings > Capabilities, build a ZIP that contains the billing-tracker folder, and upload it in Customize > Skills with + > Create skill > Upload a skill:

git clone https://github.com/jirawatp/billing-tracker-agent-plugins
cd billing-tracker-agent-plugins/skills
zip -r billing-tracker.zip billing-tracker

ChatGPT

Custom MCP servers with full tool support are available on ChatGPT Business, Enterprise and Edu, on the web only. On Business, only workspace admins and owners can add one; on Enterprise and Edu, admins and the members they authorize can. Pro accounts can connect custom MCP servers with read and fetch access only, so Bill Tracker's tools that change data are not available there.

  1. Open Plugins in ChatGPT, select the + button, then Add custom MCP server.
  2. Enter the name Bill Tracker and, under Connection, the URL https://bills.jirawat.dev/mcp.
  3. Choose OAuth for authentication. ChatGPT discovers the sign-in settings from the server, so leave the client ID and secret empty.
  4. Review the risk warning, select I understand and want to continue, then Create as a plugin.
  5. Review the discovered tools, install the plugin and sign in with Google or LINE when asked.
  6. In a new chat, type @ and choose Bill Tracker.

To share it with the workspace, an admin or owner publishes the plugin. ChatGPT asks you to confirm write actions according to the plugin's permissions.

Codex (CLI, IDE extension and ChatGPT desktop app)

The Codex CLI, the Codex IDE extension and the ChatGPT desktop app share ~/.codex/config.toml, so you only set this up once. Install the plugin, which adds the MCP server and the skill:

codex plugin marketplace add jirawatp/billing-tracker-agent-plugins
codex plugin add billing-tracker@billing-tracker

After adding the marketplace you can also install the plugin from the Plugins directory in the ChatGPT desktop app.

To add only the server:

codex mcp add bills --url https://bills.jirawat.dev/mcp

which writes this to ~/.codex/config.toml:

[mcp_servers.bills]
url = "https://bills.jirawat.dev/mcp"

Sign in with codex mcp login bills (add --no-browser on a remote machine), or select Authenticate next to the server in the MCP servers settings of the desktop app or IDE extension. Codex requests every permission the server advertises (account deletion is never one of them). To grant only the basics while staying signed in, run codex mcp login bills --scopes bills:read,bills:write,offline_access.

Cursor

Install in Cursor

The button opens Cursor and asks you to confirm. The same install link as a Cursor deeplink:

cursor://anysphere.cursor-deeplink/mcp/install?name=bills&config=eyJ1cmwiOiJodHRwczovL2JpbGxzLmppcmF3YXQuZGV2L21jcCJ9

Or add the server to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

{
  "mcpServers": {
    "bills": {
      "url": "https://bills.jirawat.dev/mcp"
    }
  }
}

Cursor runs the sign-in flow when the server first connects. Manage the server, or sign in again, from Customize.

For the plugin with the skill: Cursor installs plugins from the Cursor Marketplace and team marketplaces. Until Bill Tracker is listed there, load it as a local plugin, then restart Cursor or run Developer: Reload Window:

git clone https://github.com/jirawatp/billing-tracker-agent-plugins ~/.cursor/plugins/local/billing-tracker

On Teams and Enterprise plans an admin has to allow local plugin imports.

VS Code and GitHub Copilot

Install in VS Code Install in VS Code Insiders

Or from a terminal:

code --add-mcp '{"name":"bills","type":"http","url":"https://bills.jirawat.dev/mcp"}'

Or add it to .vscode/mcp.json in a workspace, or to your user mcp.json (run MCP: Open User Configuration):

{
  "servers": {
    "bills": {
      "type": "http",
      "url": "https://bills.jirawat.dev/mcp"
    }
  }
}

VS Code asks you to sign in the first time the server starts. Use MCP: List Servers to start, stop or sign in to the server again.

For the plugin with the skill, make sure the chat.plugins.enabled setting is on, run Chat: Install Plugin From Source and enter https://github.com/jirawatp/billing-tracker-agent-plugins. To receive updates through a marketplace instead, add this repository to the chat.plugins.marketplaces setting and install Bill Tracker from the Extensions view (search for @agentPlugins):

{
  "chat.plugins.marketplaces": [
    "jirawatp/billing-tracker-agent-plugins"
  ]
}

GitHub Copilot CLI

Install the plugin, which adds the MCP server and the skill:

copilot plugin marketplace add jirawatp/billing-tracker-agent-plugins
copilot plugin install billing-tracker@billing-tracker

To add only the server:

copilot mcp add --transport http bills https://bills.jirawat.dev/mcp

When the server shows needs-auth, run /mcp auth bills in Copilot CLI and sign in. VS Code also picks up plugins and servers that you add with Copilot CLI.

Gemini CLI

Gemini CLI now serves Gemini Code Assist and API key users; individual Google accounts moved to Antigravity CLI in June 2026. Install the extension, which adds the MCP server and the skill:

gemini extensions install https://github.com/jirawatp/billing-tracker-agent-plugins

Restart Gemini CLI, then run /mcp auth bills to sign in. Update later with gemini extensions update billing-tracker.

To add only the server:

gemini mcp add --scope user --transport http bills https://bills.jirawat.dev/mcp

Antigravity CLI

Install the plugin, which adds the MCP server and the skill:

agy plugin install https://github.com/jirawatp/billing-tracker-agent-plugins

To sign in, run /mcp, select bills, choose Authenticate, finish signing in in your browser, then paste the code it shows back into the terminal.

To add only the server, which writes serverUrl to ~/.gemini/config/mcp_config.json:

agy mcp add bills https://bills.jirawat.dev/mcp

If you already installed the Gemini CLI extension, agy plugin import gemini converts it.

Windsurf

In Cascade's MCP menu choose Open MCP config file (on current versions this is ~/.config/devin/mcp_config.json, or %AppData%\devin\mcp_config.json on Windows; older versions use ~/.codeium/windsurf/mcp_config.json) and add:

{
  "mcpServers": {
    "bills": {
      "serverUrl": "https://bills.jirawat.dev/mcp"
    }
  }
}

Press the refresh button in the MCP panel. Cascade asks you to sign in the first time it uses the server.

Cline

In the Cline panel open MCP Servers, then the Remote Servers tab. Enter the name bills and the URL https://bills.jirawat.dev/mcp, choose Streamable HTTP, and select Add Server. When Cline reports that the server needs authentication, select Authenticate and sign in in your browser.

To edit the settings file instead (Configure MCP Servers in the extension, or ~/.cline/data/settings/cline_mcp_settings.json for the Cline CLI):

{
  "mcpServers": {
    "bills": {
      "type": "streamableHttp",
      "url": "https://bills.jirawat.dev/mcp",
      "disabled": false,
      "autoApprove": []
    }
  }
}

Keep "type": "streamableHttp". Without it Cline uses the legacy SSE transport, which this server does not support.

Zed

Open Settings > AI > MCP Servers, select Add Server, then Add Remote Server. Or add this to your settings file (zed: open settings file):

{
  "context_servers": {
    "bills": {
      "url": "https://bills.jirawat.dev/mcp"
    }
  }
}

With no Authorization header configured, Zed runs the standard MCP sign-in flow. External agents that Zed runs over ACP do not share that sign-in; configure the server in those agents directly.

Other clients (stdio only)

For clients that can only start local MCP servers, run mcp-remote as a bridge. It needs Node.js, opens the browser for sign-in and keeps tokens in ~/.mcp-auth. It passes your client's protocol handshake through unchanged, so the client itself still needs to speak MCP 2025-06-18 or newer.

{
  "mcpServers": {
    "bills": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@latest",
        "https://bills.jirawat.dev/mcp",
        "--transport",
        "http-only"
      ]
    }
  }
}

This is the mcpServers format most clients use, including the local claude_desktop_config.json of Claude Desktop (where a custom connector is the better choice).

Skill only

The billing-tracker skill follows the Agent Skills specification, so any agent that supports skills can use it next to one of the server setups above. With the skills CLI:

npx skills add jirawatp/billing-tracker-agent-plugins

It asks which agents to install to; add -g to install for your user instead of the current project. You can also copy skills/billing-tracker into your agent's skills folder.

Headless agents: personal access tokens

Scripts, CI jobs and agents that cannot open a browser can use a personal access token instead of OAuth.

  1. Open Settings > Connected AI agents in Bill Tracker and select Create personal access token. Name it, pick its permissions and expiry, and copy the token. It is shown only once.
  2. Store it as a secret, for example in an environment variable named BILL_TRACKER_TOKEN.
  3. Send it on every request as a bearer token:
Authorization: Bearer <token>

The server treats a personal access token exactly like a signed-in session with the permissions you picked. It expires on the date you chose; revoke or replace it on the same settings page.

Claude Code. Single quotes keep ${BILL_TRACKER_TOKEN} as a reference that Claude Code reads when it connects:

claude mcp add --transport http --scope user bills https://bills.jirawat.dev/mcp \
  --header 'Authorization: Bearer ${BILL_TRACKER_TOKEN}'

For claude -p in CI, pass a file like this with --mcp-config:

{
  "mcpServers": {
    "bills": {
      "type": "http",
      "url": "https://bills.jirawat.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${BILL_TRACKER_TOKEN}"
      }
    }
  }
}

Codex, in ~/.codex/config.toml (or codex mcp add bills --url https://bills.jirawat.dev/mcp --bearer-token-env-var BILL_TRACKER_TOKEN):

[mcp_servers.bills]
url = "https://bills.jirawat.dev/mcp"
bearer_token_env_var = "BILL_TRACKER_TOKEN"

Cursor, in mcp.json:

{
  "mcpServers": {
    "bills": {
      "url": "https://bills.jirawat.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:BILL_TRACKER_TOKEN}"
      }
    }
  }
}

VS Code, in .vscode/mcp.json. VS Code asks for the token once and stores it securely:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "bill-tracker-token",
      "description": "Bill Tracker personal access token",
      "password": true
    }
  ],
  "servers": {
    "bills": {
      "type": "http",
      "url": "https://bills.jirawat.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${input:bill-tracker-token}"
      }
    }
  }
}

GitHub Copilot CLI (single quotes keep the variable reference):

copilot mcp add --transport http --header 'Authorization: Bearer ${BILL_TRACKER_TOKEN}' bills https://bills.jirawat.dev/mcp

Gemini CLI and Antigravity CLI store the token itself in their settings:

gemini mcp add --scope user --transport http --header "Authorization: Bearer $BILL_TRACKER_TOKEN" bills https://bills.jirawat.dev/mcp
agy mcp add --header "Authorization: Bearer $BILL_TRACKER_TOKEN" bills https://bills.jirawat.dev/mcp

Windsurf and Cline expand ${env:...} in headers:

{
  "mcpServers": {
    "bills": {
      "serverUrl": "https://bills.jirawat.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:BILL_TRACKER_TOKEN}"
      }
    }
  }
}

For Cline, use the "type": "streamableHttp" and "url" keys from the Cline section with the same headers block.

Zed does not expand variables in headers, so the token goes in the settings file itself: add "headers": { "Authorization": "Bearer <token>" } to the bills entry.

mcp-remote. To keep the token out of the process list, put the header in a file (one Name: value line, for example Authorization: Bearer <token>) and pass it with --header-file:

{
  "mcpServers": {
    "bills": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@latest",
        "https://bills.jirawat.dev/mcp",
        "--transport",
        "http-only",
        "--header-file",
        "/path/to/bill-tracker-headers.txt"
      ]
    }
  }
}

What your agent can do

The server offers 30 tools, 3 resources and 1 prompt. Each tool needs one of the permissions listed above. Deleting bills, unlinking LINE and deleting your account only run with an explicit confirmation in the request (a bulk-delete dry run, which deletes nothing, does not need one), deleting your account also needs the separate approval described above, and the skill asks you before it signs you out everywhere.

Bill dates

Bill writes accept calendar dates in exact YYYY-MM-DD form. Years 2400 to 2699 inclusive are interpreted as Buddhist Era: the server subtracts 543 before checking the resulting Gregorian date. For example, 2569-10-20 stores 2026-10-20, and 2567-02-29 stores the valid leap day 2024-02-29. 2566-02-29 is rejected because 2023-02-29 does not exist. Years outside that range are unchanged, so the range also deliberately covers dates that could otherwise look like distant Gregorian years.

The rule applies only to bill date fields (dueDate, paidDate, scheduleDate, nextStatementDate) when writing through the app, LINE/chat, CSV import or MCP. Query and report dates stay Gregorian. Timestamps and existing history are not converted; an update that leaves a legacy value exactly unchanged preserves it.

Bills

ToolWhat it doesPermission
bills.listList your bills in a bucket: all, open, overdue, due soon, unconfirmed, top priority, paid or this month. Returns up to 500 at a time and says when there are morebills:read
bills.getFetch one bill by id or short referencebills:read
bills.queryFilter bills by status, due dates, category, payment method and flagsbills:read
bills.searchSearch bill names and notesbills:read
bills.recentlyChangedBills changed in the last N daysbills:read
bills.byRefTurn a short reference from the LINE chatbot into a billbills:read
bills.createAdd a billbills:write
bills.updateChange a billbills:write
bills.markPaidMark a bill fully paidbills:write
bills.recordPaymentRecord a partial paymentbills:write
bills.setAmountSet the amount and mark it confirmedbills:write
bills.confirmConfirm an estimated amountbills:write
bills.scheduleMark a bill scheduled for payment on a datebills:write
bills.toggleTopPriorityPin or unpin a bill as top prioritybills:write
bills.deleteDelete a bill (destructive)bills:delete
bills.bulkDeleteDelete up to 500 bills; a dry run previews without deleting (destructive)bills:delete

Summaries and reports

ToolWhat it doesPermission
summary.kpisOverdue count, unpaid total, bills due in the next 7 days, top-priority countbills:read
summary.monthWhat you paid this month and the average unpaid amountbills:read
summary.chatbotThe LINE chatbot's summary as databills:read
reports.spendMonthly spending report over 3, 6 or 12 monthsreports:read
reports.spendDigestA one-paragraph spending summaryreports:read
reports.paidMonthlyAverageAverage paid per month over the last N monthsreports:read

Account, LINE and chat

ToolWhat it doesPermission
account.exportExport all of your dataaccount:read
account.deleteDelete your account and all of its data (destructive; needs the separate approval)account:delete
account.revokeSessionsSign you out of Bill Tracker on every device (destructive)account:manage
lineLink.statusWhether LINE is linked and daily reminders are online:read
lineLink.setNotifyEnabledTurn daily LINE reminders on or offaccount:manage
lineLink.unlinkUnlink your LINE account; bills stay (destructive)account:manage
chat.parseCommandParse a Thai or English LINE chatbot command without running itchat:read
chat.runRun a LINE chatbot command; commands that change data need confirmationbills:read or chat:write for read commands; chat:write for changes; deletion also needs bills:delete

The read commands of chat.run are help, list, due, overdue, unconfirmed and summary, including their supported Thai aliases. Existing chat:write tokens can run those commands without bills:read. The chat:read permission only parses commands through chat.parseCommand and grants no financial data access. The tool keeps its destructive annotation, so a client may still ask for confirmation before a read command.

Resources and prompt

NameWhat it is
bill://<id>One bill as JSON
summary://todayToday's summary
report://spend/<yyyy-mm>The spending report for the period ending with that month
summarize-month promptSummarizes one month's spending; takes month as YYYY-MM

When a tool fails

A failed tool call comes back as a tool result marked isError: true, with a stable code in structuredContent.error, so the agent can read what went wrong and correct itself. For example:

{
  "isError": true,
  "content": [
    {
      "type": "text",
      "text": "No bill with that id."
    }
  ],
  "structuredContent": {
    "error": {
      "code": 1001,
      "kind": "not-found",
      "message": "No bill with that id."
    }
  }
}
CodeKindMeaning
-32602invalid-paramsThe arguments do not match the tool's input schema
1001not-foundNo such bill, or it belongs to another account
1002invalid-billA bill value was rejected, for example a scheduled bill without a schedule date
1003forbiddenThe data belongs to another account
1004confirm-requiredA destructive call was sent without its confirmation
1005rate-limitedToo many requests in a short time
1006upstream-firestoreBill Tracker's database had a temporary problem
1007insufficient-scopeA permission you have not granted is needed

Protocol-level failures are JSON-RPC errors instead: -32602 for a tool name the server does not have, -32603 for an internal error (its message carries a short reference), and -32022 for an unsupported protocol version.

Tool changes and deprecations

The server treats its tools as a versioned public contract, because some hosts, ChatGPT among them, keep calling the tool list they saw when you added the plugin until an admin refreshes it.

  • New tools, new optional inputs, new optional output fields and new error codes can appear at any time. Existing setups keep working.
  • A tool is never renamed, removed or made stricter in place. The server adds the new tool next to the old one, marks the old one with a deprecation notice, and removes it only after the deprecation has been announced here for the whole deprecation window.

Current deprecations: none. Any future deprecation is listed here with the deprecated tool, its replacement and the date it will be removed.

Troubleshooting

The sign-in window does not open. Copy the sign-in URL from your client into a browser. On a remote machine use claude mcp login bills --no-browser or codex mcp login bills --no-browser and paste the redirect URL back. Gemini CLI needs a local browser for sign-in; use a personal access token there instead.

The server shows "needs authentication" or 401 Unauthorized. Sign in again: /mcp in Claude Code, codex mcp login bills, /mcp auth bills in Gemini CLI or Copilot CLI, or Authenticate in Cline and Antigravity. Your session may have expired or been revoked under Connected AI agents. With a personal access token, check that the header is exactly Authorization: Bearer <token> with no quotes or trailing spaces, that the token has not expired, and that the environment variable is set where the client starts.

A tool fails with insufficient_scope, error 1007 or "needs additional permissions". The agent needs a permission you have not granted yet. Approve it when your client asks, or sign in to the server again; in Claude Code, open /mcp and authenticate the server again. For a personal access token, create a new token that includes the permission. If the missing permission is account:delete, approve it on the Connected AI agents page instead; clients cannot request it during sign-in.

You have to sign in again about every hour. Your client did not ask for offline_access, so it cannot renew the session. Sign in to the server again; with Codex, include offline_access in --scopes.

Claude Code reports a server with a "url" but no "type". Add "type": "http" to the server entry.

Cline fails to connect or falls back to SSE. Set "type": "streamableHttp" on the server entry.

Opening the server URL in a browser shows 405 Method Not Allowed. That is expected. The endpoint accepts only MCP requests sent with POST.

The client reports an unsupported protocol version (-32022) or cannot initialize. The server supports MCP 2025-11-25 and 2025-06-18. An initialize offer of another revision is answered with 2025-11-25; the client decides whether it can continue. Error -32022 means a request used an unsupported MCP-Protocol-Version header. Update your client if it cannot use a supported revision. Clients limited to 2025-03-26 or older may not connect; mcp-remote passes the client's own handshake through.

The agent reports error -32603 with a short reference. That is an internal server error, not a problem with your setup. Try again later; if it keeps happening, open an issue in this repository and include the reference.

Tools are missing or out of date. The server does not push tool-list changes, so restart the client or refresh the server: MCP: Reset Cached Tools in VS Code or the refresh button in Windsurf. ChatGPT keeps a snapshot of the tools from when the plugin was created. Existing tools keep working (see Tool changes and deprecations); a workspace admin refreshes the snapshot from the plugin's settings to pick up new ones.

Every tool appears twice. You installed the plugin and also added the server by hand. Remove one of them.

Zed sends ${MY_TOKEN} literally. Zed does not expand environment variables in headers. Paste the token itself, or remove the header and use OAuth.

Sign-in fails with a client registration or redirect error. Remove any OAuth client ID or secret you entered, for example in a connector's advanced settings, so the client registers itself, then try again.

Antigravity signs in but tool calls still return 401. Update agy; early versions did not send the OAuth token on MCP requests. As a workaround, add the server with a personal access token.

Start over. Remove the server or plugin, clear its stored sign-in (in Claude Code open /mcp and choose Clear authentication; run codex mcp logout bills; for mcp-remote delete ~/.mcp-auth), revoke the old connection under Connected AI agents, then set it up again.

Check the server yourself. Without a token the server should answer 401 Unauthorized with a WWW-Authenticate: Bearer resource_metadata="..." header that starts the sign-in discovery:

curl -i -X POST https://bills.jirawat.dev/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

With a personal access token it should list the tools. The server is stateless, so a single request carrying the protocol version header should be enough:

curl -sS https://bills.jirawat.dev/mcp \
  -H "Authorization: Bearer $BILL_TRACKER_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

For an interactive check, run npx @modelcontextprotocol/inspector, choose the Streamable HTTP transport and connect to https://bills.jirawat.dev/mcp.

Repository layout

.
├── .agents/plugins/marketplace.json  Codex and ChatGPT desktop marketplace
├── .claude-plugin/
│   ├── marketplace.json              Claude Code marketplace (also read by Copilot CLI and VS Code)
│   └── plugin.json                   Claude Code plugin manifest
├── .github/workflows/
│   ├── ci.yml                        Validation and link checks
│   └── publish-mcp-registry.yml      Manual publish to the MCP Registry
├── .mcp.json                         MCP server for the Claude Code plugin
├── config.json                       Server URL, app URL, repository and version
├── gemini-extension.json             Gemini CLI extension manifest
├── lychee.toml                       Link checker settings
├── mcp.json                          MCP server for the Agent Plugins format
├── mcp_config.json                   MCP server for Antigravity CLI
├── plugin.json                       Agent Plugins manifest (Codex, Cursor, VS Code, Copilot CLI, Antigravity CLI)
├── scripts/
│   ├── sync.mjs                      Copies config.json values into every file
│   └── validate.mjs                  Offline checks, run locally and in CI
├── server.json                       Official MCP Registry entry
└── skills/billing-tracker/
    ├── SKILL.md                      The agent skill
    └── references/tools.md           All 30 tools with permissions and inputs

Maintaining this repository

Change the server URL, repository or version

Values that repeat across files (the server URL, the app URL that hosts Connected AI agents, the repository and the version) live only in config.json. Change them there, then run:

node scripts/sync.mjs
node scripts/validate.mjs

sync.mjs rewrites every manifest and document that repeats a value, including the one-click install links. You can also pass new values directly, for example node scripts/sync.mjs --server-url https://example.com/mcp. The scripts need Node.js 18 or newer and no packages; the TOML checks also need Python 3.11 or newer.

Continuous integration

.github/workflows/ci.yml runs on every push and pull request, and weekly for links. It checks that every file matches config.json, runs scripts/validate.mjs (JSON formatting, TOML, code blocks in the docs, skill and tool-name rules, writing style), validates the manifests against their published JSON Schemas, runs claude plugin validate --strict, gemini extensions validate and the Agent Skills reference validator, and checks every link with lychee.

Publish to the MCP Registry

server.json describes the server for the official MCP Registry as io.github.jirawatp/billing-tracker; publishing proves ownership of that namespace through GitHub. Once the server is live, run the Publish to MCP Registry workflow from the Actions tab, or publish from a terminal with mcp-publisher:

mcp-publisher login github
mcp-publisher publish

Documentation truncated — see the full README on GitHub.

Reviews

No reviews yet

Be the first to review this server!