mirror of
https://github.com/firecrawl/firecrawl-mcp-server.git
synced 2026-08-30 17:12:32 +08:00
instructions: name the developer index in the full profile
The full-profile MCP instructions omitted the developer index entirely, while the search-only profile already described it. Add one capability sentence naming firecrawl_developer_search (and the categories fallback). The keyless profile is left unchanged: its instruction text stays scoped to the keyless tool surface (Search, Scrape, Parse). Also extend the metadata-policy test gates to the full, keyless, and account profile instructions, so future rewrites of these constants into routing playbooks fail in CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
Karan Lokchandani
parent
a96250d21c
commit
e8484dfa0a
+1
-1
@@ -884,7 +884,7 @@ const openAiAppsChallengeToken = normalizeHeader(
|
||||
process.env.OPENAI_APPS_CHALLENGE_TOKEN
|
||||
);
|
||||
|
||||
const FULL_PROFILE_INSTRUCTIONS = `Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and asynchronous research. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent starts multi-source research whose result is read with firecrawl_agent_status. For biomedical, life-science, clinical, or arXiv literature, the firecrawl_research_* tools search a paper index of abstracts and full text; firecrawl_search with categories: ["research"] is a website filter over ordinary web results and reaches different sources. Provide only the required inputs and account for stated network or external side effects.`;
|
||||
const FULL_PROFILE_INSTRUCTIONS = `Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and asynchronous research. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent starts multi-source research whose result is read with firecrawl_agent_status. For biomedical, life-science, clinical, or arXiv literature, the firecrawl_research_* tools search a paper index of abstracts and full text; firecrawl_search with categories: ["research"] is a website filter over ordinary web results and reaches different sources. For a programming question — code behaviour, a library or framework, an API contract, an error message, or a known bug — firecrawl_developer_search (or firecrawl_search with categories: ["developer"]) searches an index of GitHub issues, merged pull requests, READMEs, and curated documentation sites. Provide only the required inputs and account for stated network or external side effects.`;
|
||||
const KEYLESS_PROFILE_INSTRUCTIONS = `Without authentication, this endpoint exposes Search, Scrape, and Parse with usage limits. An OAuth connection or Authorization bearer API key exposes account tools; unavailable tools return connection guidance. Firecrawl provides web search, page retrieval, site URL discovery, multi-page collection, structured page data, monitoring, and asynchronous research. Match the requested operation to the tool boundary: firecrawl_scrape retrieves one supplied page and can return JSON matching a supplied schema, firecrawl_map enumerates URLs under a site without retrieving their content, and firecrawl_agent starts multi-source research whose result is read with firecrawl_agent_status. For biomedical, life-science, clinical, or arXiv literature, firecrawl_search with categories: ["research"] filters ordinary web results to research-affiliated websites; the firecrawl_research_* tools search a separate paper index of abstracts and full text and become available once an OAuth connection or Authorization bearer API key is present. Provide only the required inputs.`;
|
||||
|
||||
// The search surface exposes web/research search only. Its instructions and tool
|
||||
|
||||
@@ -751,6 +751,49 @@ test('primary search profile agent language satisfies metadata policy gates', as
|
||||
);
|
||||
});
|
||||
|
||||
test('keyless full-surface instructions satisfy the same metadata policy gates', async (t) => {
|
||||
// FASTMCP_ENDPOINT '/v2/mcp' (not '/v2/mcp-oauth') makes this the keyless
|
||||
// profile, whose instructions must stay descriptive rather than becoming an
|
||||
// imperative routing playbook.
|
||||
const { fullPort } = await startHostedServer(t);
|
||||
const headers = { 'x-api-key': 'fc-keyless-metadata' };
|
||||
const initialize = await initializeProfile(fullPort, '/v2/mcp', headers);
|
||||
const tools = await listToolDefinitions(fullPort, '/v2/mcp', headers);
|
||||
|
||||
assertAgentMetadataPolicy(
|
||||
[initialize.instructions, ...tools.map((tool) => tool.description ?? '')],
|
||||
assert
|
||||
);
|
||||
});
|
||||
|
||||
test('account (mcp-oauth) full-surface instructions satisfy the same metadata policy gates', async (t) => {
|
||||
const accountResource = 'https://mcp.firecrawl.dev/v2/mcp-oauth';
|
||||
const backend = await startFakeBackend({ introspectionAud: accountResource });
|
||||
t.after(() => backend.close());
|
||||
const port = await getFreePort();
|
||||
const child = spawnServer({
|
||||
CLOUD_SERVICE: 'true',
|
||||
HTTP_STREAMABLE_SERVER: 'true',
|
||||
FASTMCP_ENDPOINT: '/v2/mcp-oauth',
|
||||
FIRECRAWL_API_URL: backend.url,
|
||||
FIRECRAWL_MCP_RESOURCE_URL: accountResource,
|
||||
FIRECRAWL_OAUTH_ISSUER: backend.url,
|
||||
FIRECRAWL_OAUTH_INTROSPECT_SECRET: 'test-secret',
|
||||
PORT: String(port),
|
||||
});
|
||||
t.after(() => stopChild(child));
|
||||
await waitForHealth(port, child);
|
||||
|
||||
const headers = { authorization: 'Bearer fco_account_metadata' };
|
||||
const initialize = await initializeProfile(port, '/v2/mcp-oauth', headers);
|
||||
const tools = await listToolDefinitions(port, '/v2/mcp-oauth', headers);
|
||||
|
||||
assertAgentMetadataPolicy(
|
||||
[initialize.instructions, ...tools.map((tool) => tool.description ?? '')],
|
||||
assert
|
||||
);
|
||||
});
|
||||
|
||||
test('primary search profile fails closed unless the canonical OAuth-only flag is enabled', async (t) => {
|
||||
const port = await getFreePort();
|
||||
const child = spawnServer({
|
||||
|
||||
Reference in New Issue
Block a user