External agents
The guide for connecting an external agent, and for operating Tender Town through it.
What you can do
Tender Town tracks public tenders, grants and market news across Europe. This server lets an external agent do the work a person does in the product: set the radar up, and read what it found.
The agent acts as the account that owns the token. Every call is checked against that account and against the workspace owner’s plan. A call the plan does not include is refused, with the reason.
How the product is organised
Workspace
A workspace holds scopes and members. The workspace open in the browser decides what Home, Tenders, News, History and Community show. Creating a workspace from here does not switch that.
Limits follow the workspace owner’s plan, not a member’s own plan. Pass workspace_id to choose one. If you omit it, the account’s current workspace is used.
What a scope is
A scope is one configuration of the radar: what to look for, and how its agents behave. There are three kinds.
- General is the shared default. Every account can read it. A workspace can hide it only while another scope is switched on. It cannot be renamed or given new instructions.
- A catalog scope is a shared scope Tender Town publishes. Turning it on for a workspace uses one scope slot. It cannot be renamed.
- A custom scope belongs to one workspace. Starter includes 1 besides General, Pro includes 5, Teams is unlimited. Free includes none.
Scope agents
Each scope has five agents you can configure. Search and triage run on the platform’s schedule. The other three run only when you ask, and each run is counted.
- Search Agent finds tenders and news on TED, the web and the sources the workspace follows. Plain-language instructions are turned into its search configuration. Saving them does not fetch results immediately. Search runs with the pipeline, as often as the plan allows: once a day on Free, twice on Starter, three times on Pro, six times on Teams.
- Triage Agent scores each find and sorts tenders, grants and news. Instructions rewrite its prompt. It runs on the same schedule as search.
- Tender Evaluation Agent checks one tender against the scope, scores the fit and advises. Starter includes 1 run a month, Pro 5, Teams unlimited. Not on Free.
- Proposal Manager Agent writes a proposal brief from that evaluation: the requirements, the references the scope already has, the gaps and the steps. Teams only, and only after an evaluation exists for that scope.
- News Report Agent reads one story and writes what the team should do about it. Pro includes 50 a month, Teams unlimited. Not on Free or Starter.
Documents and the requirement list are written by the platform’s own agents. This server can read them. It cannot configure those agents, upload documents, post, comment, change the plan, or delete a workspace or a scope.
What you read
Tenders and news are the items the workspace’s active scopes have found, highest relevance first. A tender has a summary and, while the plan has requirement views left, its requirements. Community posts and comments are the public discussion. A report is the stored writing of Tender Evaluation, the Proposal Manager or the News Report Agent. Reading a stored report does not spend a run. Asking for a new one does.
How to connect
The server speaks Streamable HTTP and answers with JSON. Send Accept: application/json, text/event-stream.
The server for this site is https://tendertown.io/api/mcp.
Send the header Authorization: Bearer and a token that starts with tt_. The user creates it in Account, under External agents. It is shown once. An account can keep 8 live tokens. No token, or a revoked token, is rejected with HTTP 401. Do not ask for the token where other people can see it.
Cursor
Add a remote MCP server. In mcp.json, paste the token in place of tt_YOUR_TOKEN.
{
"mcpServers": {
"tender-town": {
"url": "https://tendertown.io/api/mcp",
"headers": { "Authorization": "Bearer tt_YOUR_TOKEN" }
}
}
}Claude
In Claude Code or Claude Desktop, add a remote HTTP server at https://tendertown.io/api/mcp and send the header Authorization: Bearer tt_YOUR_TOKEN. In Claude Code’s settings that is:
{
"mcpServers": {
"tender-town": {
"type": "http",
"url": "https://tendertown.io/api/mcp",
"headers": { "Authorization": "Bearer tt_YOUR_TOKEN" }
}
}
}Other clients
A client that only talks to a local program can bridge to this server with mcp-remote:
{
"mcpServers": {
"tender-town": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://tendertown.io/api/mcp", "--header", "Authorization: Bearer tt_YOUR_TOKEN"]
}
}
}Start here
Call get_account before you change anything. It returns the plan, what is left this month, and the workspaces you belong to, each with an id, a name, your role and the owner’s plan.
In the limits, null means unlimited and 0 means the plan does not include it. remaining is null when the limit is unlimited. Pass a workspace id from that list on later calls.
Plans
Limits follow the workspace owner’s plan.
- Free: 1 workspace, no custom scopes, no evaluations, no proposal briefs, no news reports, requirements on 2 tenders a month.
- Starter: 1 workspace, 1 scope besides General, 1 evaluation a month, requirements on 10 tenders a month.
- Pro: 1 workspace, 5 scopes besides General, 5 evaluations a month, 50 news reports a month, requirements on every tender.
- Teams: unlimited workspaces, members, scopes, evaluations, proposal briefs and news reports.
A catalog scope that is switched on uses a scope slot. General does not. Inviting a member needs Teams, and an admin of that workspace. Editing scopes and agents needs an admin, on a plan that allows customizing. A member can read.
A normal job
- Call get_account and pick a workspace_id.
- Call list_scopes. Decide whether to create a custom scope or turn a catalog scope on.
- Call list_scope_agents, then configure_scope_agent with plain-language instructions. Switch a gated agent on only when included is true.
- Call list_tenders or list_news, then get_tender or get_news for one id from that list.
- Call get_scope_report to read a report that already exists. Call run_scope_agent only when the user wants a new run and the plan has runs left.
Examples
- List the tenders in my current workspace and tell me which ones close this month.
- Create a scope for hospital IT tenders in Portugal, and set the Search Agent to follow that.
- Read the stored news report for this story. If there is none, and the plan has runs left, write one.
Tools
get_account
Purpose: know who you are acting as, and what the plan still allows, before you create or run anything.
How: no arguments. You get the plan, the month’s usage and the workspaces.
list_workspaces
Purpose: choose where to work when the account has more than one workspace.
How: no arguments. You get each workspace’s id, name, your role, the owner and the plan.
create_workspace
Purpose: open another place for scopes and members, when the plan includes another workspace.
How: name, at least 2 characters. You get the new id and name. The workspace open in the browser does not change. Free, Starter and Pro include one workspace. Teams is unlimited.
invite_member
Purpose: add a person to a workspace.
How: workspace_id, an optional email, and role admin or member. You must be an admin, and the workspace owner must be on Teams. You get a link that works for 14 days.
list_scopes
Purpose: see General, the catalog and this workspace’s own scopes, and how many scope slots are used.
How: optional workspace_id. You get planScopes (null when unlimited), used, canCustomize, and each scope’s id, name, kind (general, catalog or custom), whether it is active, and whether you can edit it.
create_scope
Purpose: make a custom radar for this workspace.
How: workspace_id, name, and optional instructions describing what it should follow. It uses one scope slot. Not included on Free. You must be an admin on a plan that allows customizing.
update_scope
Purpose: rename a custom scope, change what it is about, or switch it on or off.
How: scope_id, and any of name, instructions and active. For General, the only change allowed is active, and only while another scope is on. Pass workspace_id so the right workspace shows or hides General. Catalog scopes cannot be edited here.
set_catalog_scope
Purpose: follow or stop following a shared catalog scope.
How: workspace_id, scope_id and enabled. Turning one on uses a scope slot. You must be an admin.
list_scope_agents
Purpose: see the five scope agents, whether the plan includes each one, and whether it is switched on.
How: scope_id and optional workspace_id. You get each agent’s key, name, role, included, enabled, instructions and whether its prompt has been customised. included is false when the plan does not have that agent. Do not try to switch it on.
configure_scope_agent
Purpose: tell a scope agent how to work, or switch it on or off.
How: scope_id, agent (search, triage, tender_evaluation, proposal_manager or news_report), and any of enabled, instructions and, for search only, search_config. Instructions are plain language. For search they are parsed into the search configuration. For the others they rewrite that agent’s prompt. Send instructions unless you are handing back a search_config you were given. Empty instructions clear the customisation. Switching a gated agent on fails when the plan does not include it. The call can take a while. You must be an admin of a custom scope, on a plan that allows customizing.
list_tenders and get_tender
Purpose: read the tenders the workspace’s active scopes have found. This does not run an agent.
How: list_tenders takes optional workspace_id and limit (1 to 30, default 20), highest relevance first. get_tender takes the id from that list. You get the title, buyer, country, type, status, deadline, value and summary. Requirements are included while the plan has views left. Free counts 2 tender pages a month, Starter 10. Pro and Teams do not count them. Past the limit, the tender comes back with requirements null. An evaluation or a proposal brief is included only when the plan has that agent. Comments are included.
list_news and get_news
Purpose: read the news the active scopes have found.
How: same shape as tenders. get_news includes the News Report Agent’s stored reports, and the long summary, only on Pro and Teams. Comments are included.
list_posts, get_post and get_comments
Purpose: read the community. You cannot publish from here.
How: list_posts takes limit. get_post takes the post id and includes its comments. get_comments takes item_type (post, news or tender) and item_id, and returns that thread.
get_scope_report
Purpose: read a report that was already written, without spending a monthly run.
How: scope_id, item_id (a tender id or a news id), kind (tender_evaluation, proposal_brief or news_report) and optional workspace_id. The plan must include that agent. If none has been written, report is null.
run_scope_agent
Purpose: write a new Tender Evaluation, proposal brief or news report.
How: scope_id, item_id and agent (tender_evaluation, proposal_manager or news_report), plus workspace_id. It uses one of the workspace’s monthly runs. A re-run counts. A failed run does not. You must be an admin, and the scope must be one this workspace is viewing. It refuses when the plan does not include the agent or the month’s runs are used up. A proposal brief needs an evaluation for that scope first.
When something fails
A refused tool comes back as JSON with an error string. Say that sentence to the user. Do not retry a plan or quota error. Do not invent workspace, scope, tender, news or post ids: list or get them first. Send one tool per request.
- HTTP 401 means the token is missing, revoked, or not sent as Authorization: Bearer tt_… . The user creates a new one in Account, under External agents.
- A plan or quota error is final for that call. Do not retry it, and do not work around it.
- Saving search instructions does not fetch tenders immediately. Search and triage run on the platform’s schedule.

