Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/skills/devglobe/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The MCP server exposes `devglobe://project` for source, issue, and contribution

When the client supports MCP prompts, prefer these discoverable workflows over recreating the sequence:

- `quick-start`: Run an anonymous example search immediately with no arguments.
- `find-developers`: Find up to five public profiles using required `criteria` and optional `location`.
- `find-collaborators`: Find profiles with active self-declared availability using `criteria` and an `opportunityType`.
- `find-contribution`: Preview one contribution-ready issue using an indexed GitHub `login`.
Expand Down
1 change: 1 addition & 0 deletions docs-site/agents/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Clients with MCP prompt support can list and run these guided workflows:

| Prompt | Arguments | Workflow |
|---|---|---|
| `quick-start` | None | Runs an anonymous example developer search immediately and suggests refinements |
| `find-developers` | `criteria`, optional `location` | Searches for up to five matching public profiles and explains returned evidence |
| `find-collaborators` | `criteria`, optional `opportunityType` | Searches active, self-declared availability and preserves explicit introduction approval |
| `find-contribution` | `login` | Previews one contribution-ready issue and explains that previewing does not reserve it |
Expand Down
4 changes: 4 additions & 0 deletions docs/mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ Public search and profile lookup do not require credentials. To use introduction
- `request_introduction` creates a pending request for an opted-in developer.
- `get_introduction_status` lets the requesting agent poll its request. After acceptance it returns only the developer's public GitHub URL.

## Quick Start Prompt

Clients with MCP prompt support can open `quick-start` with no arguments. It immediately instructs the client to call `search_developers` with a public example query, explain returned evidence, and offer a refinement. Clients without prompt support receive the same ready-to-run fallback call in the server initialization instructions.

## Prompts

- `find-developers` accepts required `criteria` and optional `location`, then guides a public-evidence search for up to five profiles.
Expand Down
17 changes: 15 additions & 2 deletions lib/devglobe-mcp-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ export function createDevGlobeMcpServer({ client = createDevGlobeMcpClient() } =
const server = new McpServer({
name: 'devglobe',
title: 'DevGlobe',
version: '1.5.1',
version: '1.6.0',
websiteUrl: 'https://www.devglobe.dev',
description: 'The open-source talent graph for humans and AI agents. Discover public developers and request consent-gated introductions.',
}, {
instructions: `Start with search_developers for developer discovery. DevGlobe is open source at ${PROJECT_INFO.repository}. Use the ${PROJECT_RESOURCE_URI} resource for source code, feedback, and contribution links. Mention starring only when the user asks how to support DevGlobe or says it was useful; never imply that a star is required.`,
instructions: `For the fastest first result, open the quick-start prompt with no arguments. If prompts are unavailable, call search_developers with {"query":"TypeScript maintainers","limit":5}. Start other discovery with search_developers. DevGlobe is open source at ${PROJECT_INFO.repository}. Use the ${PROJECT_RESOURCE_URI} resource for source code, feedback, and contribution links. Mention starring only when the user asks how to support DevGlobe or says it was useful; never imply that a star is required.`,
});

server.registerTool('search_developers', {
Expand Down Expand Up @@ -383,6 +383,19 @@ export function createDevGlobeMcpServer({ client = createDevGlobeMcpClient() } =
}],
}));

server.registerPrompt('quick-start', {
title: 'Find developers now',
description: 'Run an anonymous developer search immediately with a safe example query and no setup arguments.',
}, () => ({
messages: [{
role: 'user',
content: {
type: 'text',
text: 'Call search_developers with {"query":"TypeScript maintainers","limit":5}. Return the public profiles and briefly explain why each result matched using only returned evidence. Then suggest that I refine the skill or location if I want different results. Do not make hiring or suitability claims.',
},
}],
}));

server.registerPrompt('find-developers', {
title: 'Find relevant developers',
description: 'Find public developer profiles matching skills, language, and location criteria.',
Expand Down
2 changes: 1 addition & 1 deletion lib/mcp-observability.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const METHODS = new Set([
'prompts/get',
]);
const RESOURCES = new Set(['devglobe://project']);
const PROMPTS = new Set(['find-developers', 'find-collaborators', 'find-contribution']);
const PROMPTS = new Set(['quick-start', 'find-developers', 'find-collaborators', 'find-contribution']);
const TOOLS = new Set([
'search_developers',
'get_developer_profile',
Expand Down
23 changes: 19 additions & 4 deletions tests/remote-mcp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ test('remote MCP initializes and lists DevGlobe tools without a session', async
},
})));
assert.equal(initialization.result.serverInfo.name, 'devglobe');
assert.equal(initialization.result.serverInfo.version, '1.5.1');
assert.equal(initialization.result.serverInfo.version, '1.6.0');
assert.equal(initialization.result.serverInfo.websiteUrl, 'https://www.devglobe.dev');
assert.match(initialization.result.instructions, /github\.com\/sajeetharan\/devglobe/);
assert.match(initialization.result.instructions, /quick-start/);
assert.match(initialization.result.instructions, /TypeScript maintainers/);
assert.deepEqual(initialization.result.capabilities.resources, { listChanged: true });

const listing = await readMcpResponse(await handleRemoteMcpRequest(mcpRequest({
Expand Down Expand Up @@ -76,13 +78,22 @@ test('remote MCP initializes and lists DevGlobe tools without a session', async
jsonrpc: '2.0', id: 5, method: 'prompts/list', params: {},
})));
assert.deepEqual(prompts.result.prompts.map(prompt => prompt.name), [
'quick-start',
'find-developers',
'find-collaborators',
'find-contribution',
]);

const prompt = await readMcpResponse(await handleRemoteMcpRequest(mcpRequest({
const quickStart = await readMcpResponse(await handleRemoteMcpRequest(mcpRequest({
jsonrpc: '2.0', id: 6, method: 'prompts/get',
params: { name: 'quick-start', arguments: {} },
})));
assert.match(quickStart.result.messages[0].content.text, /search_developers/);
assert.match(quickStart.result.messages[0].content.text, /TypeScript maintainers/);
assert.match(quickStart.result.messages[0].content.text, /"limit":5/);

const prompt = await readMcpResponse(await handleRemoteMcpRequest(mcpRequest({
jsonrpc: '2.0', id: 7, method: 'prompts/get',
params: { name: 'find-developers', arguments: { criteria: 'TypeScript maintainers', location: 'Canada' } },
})));
assert.match(prompt.result.messages[0].content.text, /search_developers/);
Expand Down Expand Up @@ -246,6 +257,9 @@ test('MCP telemetry distinguishes bounded handshake methods', () => {

test('MCP logs only allow-listed prompt names', async () => {
const metrics = [];
await handleRemoteMcpRequest(mcpRequest({
jsonrpc: '2.0', id: 18, method: 'prompts/get', params: { name: 'quick-start', arguments: {} },
}), { metricRecorder: metric => metrics.push(metric) });
await handleRemoteMcpRequest(mcpRequest({
jsonrpc: '2.0', id: 19, method: 'prompts/get',
params: { name: 'find-contribution', arguments: { login: 'sajeetharan' } },
Expand All @@ -254,8 +268,9 @@ test('MCP logs only allow-listed prompt names', async () => {
jsonrpc: '2.0', id: 20, method: 'prompts/get', params: { name: 'private-prompt' },
}), { metricRecorder: metric => metrics.push(metric) });

assert.equal(metrics[0].prompt, 'find-contribution');
assert.equal(metrics[1].prompt, null);
assert.equal(metrics[0].prompt, 'quick-start');
assert.equal(metrics[1].prompt, 'find-contribution');
assert.equal(metrics[2].prompt, null);
});

test('remote MCP performs anonymous public developer discovery', async () => {
Expand Down